From 858c9193cbfdaa1f019f44b9c98c12f3608aa02a Mon Sep 17 00:00:00 2001 From: Kjell Kernen Date: Sun, 2 Mar 2014 23:56:49 +0100 Subject: [PATCH] Data handling added. I have used the simplest possible channel class. An array with these channels are filled throughout the wizard, forming a simplistic mix table that can be passed on and inserted in the real mixer. The simple mixer is fully functional for planes and multicopters. I have to read up on how helicopters are controlled. Currently that part is done wrong since I have no idea about how to set up helicopter mixes. --- companion/src/companion.qrc | 1 + companion/src/images/wizard/tail.png | Bin 16645 -> 9918 bytes companion/src/images/wizard/vtail.png | Bin 0 -> 8054 bytes companion/src/wizarddialog.cpp | 346 ++++++++++++++++++++++++-- companion/src/wizarddialog.h | 88 ++++++- 5 files changed, 401 insertions(+), 34 deletions(-) create mode 100644 companion/src/images/wizard/vtail.png diff --git a/companion/src/companion.qrc b/companion/src/companion.qrc index fa38969d8..10656ba1d 100644 --- a/companion/src/companion.qrc +++ b/companion/src/companion.qrc @@ -74,6 +74,7 @@ images/wizard/tail.png images/wizard/tails.png images/wizard/throttle.png + images/wizard/vtail.png images/wizard/wingtype.png images/library/00001.png images/library/00002.png diff --git a/companion/src/images/wizard/tail.png b/companion/src/images/wizard/tail.png index 09121ed17fb8fb142d701b723636de8205c70793..50d7000d3e57478f4a4cfa7fc2ae899adcb52543 100644 GIT binary patch literal 9918 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 literal 16645 zcmb`v2{e~&`!*_4l1xb|bCOVo3L!Jil1fsUNs^(=W9DQ^5|WURM=~WsnMnvq$UG-A zg);5q`oHgf*ZZyYt-Zgs_Fj)i9`XC#_jOeek2OIr%%+a?CKCdS+jH*C$gkDWN9amkZ@I|T(d z#R(O~3y$9>VjXNBwagdGH(&q4AN{NQxD}%_C5_kps8b?>XZC4jUfrfzd{u~-l2*X$ z-t*_jnKV+FX=uWD`T2Nw)=}Vn+R9egMPJpnf2NS8Eqykolh>Mkqo)Fer-Fh=RUCJ6Wc*wS zoAQ+_yKJR7gjqMU8TCrhi$~L~uC8hbuv`-U{d<+s){kLFO~(nJ7W3Sf>FKIx&TP4T z`?kiVOB+*~Hw9Kw%FD|eo0#zI-@oPc>(|q>vtDUwLOx0c8=c&R9+mgqRpEVSxi&er zGPlp-$6%l0`SV-N&CN9~T=3btSDjl%W|#AOPQxrV_UcmeTqOY(rIcpH1dVvTVt1M? zTU4jI-!pC9>RnQz;N$D7cpy@lo3X?+N0B$IQ-Wt>jmy?dZDA?5zlS7lefPQ5@m4Xd zrL4Jmt7a;TvOm3VTpZUMo&7pjuJA;hoSCWSDmNBazYh1jWMs1}Wr@4n4;zBoXKfo<4Ot;W^hr!U$P(x2IH07By?d0TS zku&kE8U~%r0ZYal)C1os;a8} z#*C@X^k7veSExge+x8PDPCTd`Vw1KNSYBD-VX=2T)!Eg>#KPk9_pkGdl$69%kq6l1 zT%`nsg!-nYLa8^ia_`%>>D{|`QqI2wEF?N^&EeH&PbPg)m-)GqZiBFPCdI{z7ujST zMfp!hQM|jlni6_PI=0d5P+OMKMjs`f4RmaGtE$vo|Bj}Z-MHadSSZ8k_Uqj7Bu!T= zw3(&lhshYmVz<~MA%!<$INy}pdrR5=V5Dc4qQE^D&3+R4(VWt-E$K;++V0c*TMzBr zA}A>MATrYb$&;M|EVP4zgWMt_3`W%1@WY49beytm zCzF^v-rn+VxA?H%ROaCVE$ijAv9D&LY}0cM^5vF!yZ7xI{paD*gv>2PMaBHN&oWup z8#oV1O71>%h$Y9gUg_e+ZNr~qH@~||pVJ=HoO0ITZ(H2p`*m+}bNfm>sibZX($H?+ zeD2DX&9UkZElP1mT^@(3t}HJfxcq2^X`~^}zr0W37&SaQ>Nt_x%FP@Qe?d^px>rF( zMTJ{Jf|Zk#lQFRJ-u?StnyJgmJVJQ9w$eO|G~D4eug#wvb(mylr{DNIF)=JUdK0Sm z=}{L}hi<36AzbnysGPp`>v5{)=7MGA!Q$&z_ZvRj0Tc z7`VB3D?e)>xgzEO{al?4bK8H?)2XX%rswCYP#5P=X{dR#T%F^5%yjHhjF&H8ZY%bX zAH03ULSmPWj!ub9=a$Gzf)U+~BZU(~x$PEaw{8ukbUuB`ZqZe+ZOfJ|$IqOpe0eT0 z({aYo(a8yo0avqIRFsi9VEqQ~bvM7gDt&vaL)4;8^w-ap&89g!>g(%CIqPN|JAIlC ztGzg~G%?v8;U3RsG(A0ix5Zr5*;%^4e&Rm%BD<_3W5$QSg7cGIfe}KNo@Zq-Vb|r= zyEt5_O=~f?Szfex^ypFihYy^4_Uw82&p%%1M9HV4y#luG8zu!AD;{WA~CfTId8=egby_Y?DG(&Ls z_pe_*N(m*Ef!oDyeBle?Ji2q2ghk0QE;pZ`AUc+9+xiNpJ}9fGtpEJ<2o)-eZ|~lo zU-v~GE=Y%mhkHlrI&ZrDjvZTshMvAE{H$C+mQi(CYinfW_`8v3%1%y4@W$3XZVPC) z<@%!f&BNjQN^N1*r_y$`DQDySO7-zjYcD3%P$(p6 zmNqmns3kI?4NJ$;PZh7pNriZq>MPjTh&?*Fhnbmqy7{bpg3H3Br0ZXPCo9UKp&{J* z$4{Ti9_>5-;OW!4>XhO=M~>_`^;ozxr$H{Tv-9fu4I9d;t2bi2WVTyi->KcWv2W+j zoh3Hxw6wH~)$~{&^kXw~b0rH4;i96V*U}>2zkRFX>N$e`^5n@AMpjn8M~_$@J$`KX z_2oGM5fT66d}Uo|kg75ctv3@k_xcUFS&dz2pYAJ9&`ixVs;0ki;X;Xd?&{>iJoZQ6 zc9E(FJj!VCHml1{_f&Y%I*q1#OYa2)yc?$+tq9nP?MH1y=jrK*@mKIqW@$^yHjFjw z!_1BeRN{};3@%;Q8C4b*mb+qpi;Irza;|KYo)pS{bnkA=c26&h7uGw?w_lGwnPga6 zT55qcKb_JnmeO1!6;e39&@o~E*7>)&eZ$d(%=~<*;nC3=G~4rn5vREsMJbAx?8sjf z6cqHVv_}r$9_o5};sR87?Z?~1lAFw;)KiSm=S>77?yn4Rt?8HhZ85?Kvly<6#+%qV z%2wN4`t7>5nLj+>NbKib^W6cuE@BTbTMCFZ$1si~<+pT@(((sHu~{%M=ZYsTJH zS(xk+b6vEqsHjlDR4p&3diLxY7C=csfdc(IZjYHqkqWP8UY=zCzyK2`r+eiMVM$5J z@y>T!?dhO%y(FkPVsBBSwKk0`(#qt`LjoO`jvnRs{rfjSNu}SGUGYt3_$XoXZXWeH&gZ4V+b6m6 zyX3C^{{HDuk7cSvwcxUkVY{1hZ(g#U_`WSgJ=RM-g^J>%u{e#dl0d{sA0MCTte+94 zR4laA>TzO0(aFo_B&H2on!S@@ycBr_67NxTX`K;KW@-VpO}eJZNiT8N9UmR_4UPkRJ?kX z-TC)V-)Bc%c!6*E!#81EPtVNsH3a9LzjiIydm{rc@DZ6!m4=>x8Mv?~F);}j1hdfA zfDu;zv2Vw$w4eCyd*se=Z+~UradmY+lqnE^REV;>yPT4eQhe)}!J(ZpL5qf2QCtDk zl#O}%g*Z~XjHhAss~lIEt6fnIAVfC>f&2Zz<-SoOVEuU+e#oOHjKB@LWK zR=8EqBRJ0e?y+Bx;?u!P-#>QmstXsEkdTx%&h>pwc7n9s#FVzoQ z={IlRmZ2P&n3x!8eX%@d78Vs4tf3n@9VyP8JLkbBAzHN<9F8hyKXQ9Lrk;SHpi=AW zYcu0H4NCmseQ|5cdvQPA&SU#YYm3x#_f${uR^TQ*`PwxO3^L90=P}+&*+}m~-&Emc za&>d#VGU$rXQzv)-;kw^4(UuT5BLjhLNuoSUSMFk&!(-tKYyN_UFE>tD4sa6>3(3~ zIV~+efC5ZBd|*^nR96p#$V`@?F*Sbq;#D6bIe<$axs!uVL{J7U^Bf-3S-C%Cs^na6 zs9Ia;Su1UAUC2(f0;K-*=@Y>(fJ9_w06I-CEF3d1;K75`)YQZ@w#McO+9gSUXShz$ z(NU_~ZQUeX zp`j`9-3*=u=tjf9Fm<7Fm2c|epwHQ7vH^+5LY30B2FiRlV`0k{X9jFAa?lA0QVtU1 z|Ym9F43@{qBGxgU2Lt?Xs(u=dvZLsM1z(G1W+HJ3`blB6UK?%zK zhCr{5e}*En+?MRwg4Iw+wo~041bSaRa17(}!(#vDM-dST7=(EG1j&3gKMa-uID{S9 zlya5}zxC$L8*Vu{PCzT{e8uC(Y5vYnY))+YI1*H7JL+{w&uyDO1DBe*I{lX~Uo0Kp zudi|05FDgNi&K@c?xj!*V)I-_wITlPTh`E{^K9t; zXjRkSu2>lWKx+s_V3;lU)d8s}CpMvN@d^mgFvw0*@SlAagt7MZ+c(3%zeX2-x9W-M zmr&4g$+2S;a>z^j`T2o2^rL~ewhv!(=<@yX!|YLHw4GqjaE)c25n2j? zAkSPTj{tm>V#=?rt`O3L=ZglPpq2K=HX0XEX}E5BikHt<$@Aq)0l7oB?d*JY(*1C0 zxLtrZf)dEECt%1}dJu@m@Ey zpgXaOilC4?N!=8;VDA-vWDdMk_u7=jJbJs3(<%A|P{k#sIu;bHz$1(;=H*yUgD?sV9 zu(I|q|CxK4mgZe!tOTfEfQ=0pNmvpMEv*+CJ6ca)U!SMTI433N>;&}sX>bN4#L4Vb=p^4##(8c0M_Tid;(F7x`BXl;cKBEYw^vjhum!Bd|4utdLU(wI$!&=qvIyW1;K3;B|SY{H*VbE7<`?YS~^@GGt=kK#f#dX znVHcpc0Yh-wz=G%!)A@#!n#Fl z=m1hK^TMQOE-o(WPkhfMy8sip)P|i@^SygCV0{Yw;XEir?+sfp3n@Rx$%oF)-ad5b z5ch!t^jTS1)4zXLV!@`D=NgQb7iSiSBK53)e%%*!njiaUw(w$P$MX-vyW2bjM;{-! z_Q^^gvtL1gg|vuR@$UEOwPP%V z%VXJQ@$X-+0V$PZ$Ba<>Y=_Jkjm6t9uATNTx9M6+4zN0QBV9`ft$1c-p=Y3)%cEkn zIRz^ReBPLNjA409Z>>LN&Hl*p^73@AH$z!{{T540OUFLn?bF>ZQweY0uz)q8&5$+c zaOku-aVC@8BtR~KOJsCmtr@JWrs%CEe>5c$(1J1XRK|fGza$_apn$!E8t$`}iq}j9 zdv!{PIJu|i?pYKjfA~yup@u-w3y-NG00x2m`+d1ViS#shzQ1#?0lOMsR~LeDv`^5t*x!)4GkH} z58bh4w6hGUfpo}B1gIYv%P9UZK5+BqO`Elqg~Zpd$zU$U^v4Ln+&g#qa=@ogCkc8) zhX9%&w~1Cp^epUDFf|OcLx&H~jC}R-_U;=PD33Fp$5b;j6R0p06UkQK?ma7ASXhYe z0~O0tY(q@FA8-$9xV*BG+Q!BPBnZ#8LGSa(ZT5{&)>1E=+&!hYEn>}fb+77I6fVRM z1CWD{H8o@+U|Qmq2=52T;^pS1AbUeIwaEA{107w_pcATq4()%>smBV!tOIxoM2x_E zw5g#?&dg-Q%#D(=;bk*g_D@Yt-Y``(M}OdI{@wjo-cA=@+QqJy^9;};`tH01%07Pjbj9my zg@kb$)IT{Kb<{-yT8+zzz-IZti`f5A2Z2F7agTsqis@R31qDym?vgQMES`YAs-Ciy zy_(z$8X8%vzrV*EPDFI-1;iw2j&AAlEZj466oYhjc9s+kVRcjQ7dQdZ|74fM$8!^C zhwjF9gv zL`m;3Y8zr=fRUF&h_RSzn|J2thO6_kL=6~7uNUom^{WJ^u}n( z#D1=Q)>Zg@q_8ix-744UsC{AVL|c~k@5!zh)Q4Eu@d^r22m_CwJ^Re*I;}X57H}}F z<t!a-whyr_JBna?#qtz)8z~~Wo1gHc^zxN zY_8;4ngFI+l=*BTWVy~TOSFpZCM*a%bBo!*8jH3}17U9NyEQ|%lQmPdp@qoUkF(`; zOvL`p9g>>7FIOS?@XGKns0nJix}1+i^g{GJRwAtYvfHlx} zXmBv|Mssr3N9vug%d(zqIV~-Qumfq}y7z z@bMJ?j0YHE1PWp*s^Yb0zMK*8q<6~t z-MLE8iT5rGRS=Uht$O4zl(?m&7PAu@zvtdOr>W`n?#>9XmOl2D<5+qg`e}UgXk%j| z1*$y%-8&xWJp@HUK(@Y^ODFl)XHqZ8&1K2?cJ0Sqkk!L$K-c(tE4S;ZU?u`Op1XRL z031kL<+Zh&-#huw%-rXY6Amj5T5O}_V#v-)C-YMmD50F zXNPK=(k_XBwd()=*`i%wyYH9tQOJsoZEZ9m13n3W%y4ZHm&$%4+@k_1uRKZ>y=P0plyS_<1~| z)o5!#)k&rrUXl2Fr2y^RuIY4<0aLUXkqz;UY@n)=tuztUmnli`3#{ zE(IP=(lo&CCNrOrg+--bvu%1UWqfX=ArW&nO)H(ilgYvtDh(?rm5SBhDML@#KN*_Bqb^(+1Y7^vfA2zrsR7fw#H}erKl&L&$@u+O{-R+)!XQR)uG_HL#M1cWA== zj5MS_UCA|X;Yx13*Wv1aYjye0>C_9^P{3K)*gmeOT(|3>Dcuqp;ALnBr_|L=p%Yn* ze2%pMVin%EFCbRd>ERLf5c%bI9eGyQNpo<1zxt3PAMH}Y?&pQ!$;r=nOR5rV+dFse z5b;l#hsV=xd8V50K+RG$_`QV5Cl(1vc@hqjS6P{v%U)>iyOM3Z>0nH~t4w3q?qk_p z?u(v#`1mr>j>No6r~M5t3$sdqAVXi2{wg}&{XS+3m)z5REVRk! z__M%rFV9a;R0W%-IoFP7rnZ<%xc#;L*4S7=>>>V$lkKq%-8In>E<^~GFLF@j#Ji^{->DOraw+uax zj{624r+I1H*N^ z%SzXcE`8BV2KnU&6J3Ro(er$}@#^0(lc9@(5yXoDf%Av(2TgnNGy&He4^P}y?lhf! z+w9IJ%E!09IfZd${__8w1vm@3Uy50`38ooz7or>i4iT}KJe{6b-MU=B@V<6q-waR= z1RP@6pr7Npk%GlIBqIDweg2QIFuN`0#KtA+!+U`e!8WSh4#G z1qJXf@ihV1p<|T-_s zg_m}3cZ}FaQ(M*;3>2r#;HHB(WLUw5NaMpe0lRtd@Szv&`I(1MbQ?=dy2Vqb#>W9^(mkr&wwKI>8<_U z4lkUCIiL}`4?LiF*i?@F0eeNw8sj?-xbr#5FdYkFCtMU@>Q7U%*`a<=#wsuB&5!_U zCD+L6fSSxyY(2|;@y2o-$(ZTgM3!$JbG`c5aSywq-J zf))}+7_izordyt>@BRM$yM9hPBRhN0^*A?H%vZ0JldWSc6J64Y6`?m zh`D;oz}f+XVc_joKRt2>zbOir7HW+B&(Y}YEqP2ZfY~H1i8jj3NOPbgOIA#b2~H^h zJ(1lH%O_YUkD&K*!Fodw2XY#0VLU+~mO+stPY>N-rrSV;z7Q4}dF+V!!@N7fUp}m@ zx}a7O61i~kBEixPa!bN6L7MWc^l(?;igj5In)8mpxOud?jaE;5#5%4KYY>|G5 zKb}0we%y#GzysN<{#3!xkT-6P`YzPTSGwOdnV1z z%{H($iNp>OkJi`A<7tyw1u``IRJfh2IN_rOiQ!iOYw)4l4N(|sO9K2kSgT0G5W%A7 z{!jD_k9_Oh$GgW)y10Ia838{9jaRp-uI_YxVc`IraYX=xS6Vmyf3;Ty?*hgC+9wvf zFYrryHYeZI;pFGfy?P!Iw?%XoL}TD};iS^#%R4ZbsUhnO51ZnF$k|58I2=GCNXEqZ zm7C{@+3x3WrXEE+dPFp?J;4*aA23ltOE6VDA(3dMO=!5@0pS(CR=~0|c(@?=S@DV$ zTu``JgP>+Z*J%`HyADOJ{$M14~-|Fo{W3KY2D>ec6hv(o| zZ(5j~m;ostFOSbP#$Gz`p7dEdSZYgsiLLDiaWGB@iZnbE)+{%4)n|QXZ5Gqn6=a*M=|!;)qLx9==ykJ z63&7^s}2*2=o=uB!_AI-Q@7MerU}5WXt6&Kn)dSk+2SOSYz$2$Se6*ihDJtEW!A;2 zS8uMfVVAJ#4gzxK5{&ryk1sU^WHEp&=;x$WLW3lxJFH~*O==(V{K4|A*TI{B3&`{1|HzOyzFW_`h|MmzJ13}p7gqUz#oDZEJ!#Oki`GR$V6{_KSZpHCgOJUt@|i3M8tr+i(oXE-Ml$a zych8hl*Zy<_}Rthzk5PnO?cU``(rP?x>m@#_v|wt7zm)BVEDvQM~n;00Q1_%-@hEL zMRh2bKYjq^7s7tT>-lqD3~qy=PZ9a>FjqMpL=N^BfOKm^jif5!SAY5u>~TQqb@@UO zHep?TeegPcf(OEDjOi%W_OJ%Fe{fquM;YK6vz5M#cRjc>_*Hs(aPFHonGkK}>kc-E z`YM&mO9%?yPrV>WbRpC-_z@iik_pRk;SV2b$H}=xK_FOL!%V!4{Kp+B_SQkWUa854 zJxe-@v%1HsLO5!%e0Llit^->{(vbAfH#9AN<^VPdeiqtjyd++YT-~Pil;k}#f&7wN z$D*~;OyHF1Ll8BAQf>%`zyQcybZ%kcI@rVZ%xg-xI4HZ(hyfJ4FZC@>L@IFWgWa9r zW1jE4(~wnFRdtg$w$kvO<*a6#HAj1q(?NnQkZu8&?uE_kubDb7%E1LgbSwX91>kt- z>j>?L8dlH%j=j2)M~_ZJ(rB>p(UIq;dP4pDHlT|oKsN@*Lhge&-lMiKXz?{l$+yLP zrCjrroSq;HFTe}Hht!>6I`|%3Kau;=$?OWT9s3q6?-m0i4=x2t+%8{2V)t$;f@mR9 z(R-Jcq*S3mAQ@o~d{~+9IOYBp*?_ADHX6~PTshX;NwL4o$S8j9kq8gg*q9HDh#~s4 zA1Xfa)hoIWA3k_EZ<@D?n=`GbK7{p${z*(YtSP$Rix)3?5x5z!inj77pRkvau)6Sjuk&m&LQsZNxg}n*v1RlOPTQ|RU zJy*vdOPe4?>~98Ab$OOuqSrsOlQBeK7r8h%1oDrv-TWs_uhppTp0cYLwVkyRHlo9J zAZjg9K;Yugk9_Ap^TcOx(3lurK&}K;e~y)50u@M3=5L#@$GVsHS(o%#D{wP{6(sw_ z9s(vykHvhq?B>%n8IV;2>jM6N%;D4lNeWCpXkj7r- zty{&cx@8ZcK|!^L>f&2t(WP;Ok$j0wK3u0k|77BN~9kw8bE ze7~Se){H;g05F*3KM1A_-+R^&5hT~j%TQqT{Cg)R>f;W5uB-FW7FL4&8j7;HwE;25tMHJxwpyZRaj`tueDCCB2thUYD~K(T@0Vl5 zHiQi5i%08cX#)tIJAdB0+@HY+E(yuPR2ueew*}{h5RB0Dz2IO~pl!0)*qiLqwlv$e zZHqd5la;8OX9n8Gn0B3i+b7+uD|Aylx);9h{rj{;1pHWAtBl1&V!?VO*1-@`DYoLh zd-qCkrJ=Z(c!#O($fD68F(gyqvb0%9fG{8?p3t6g&% z{1`?;Cz_hf&^I%0wjKazU$^M6`w^5J9sz+LXPb>BcUSFkvN9YeBOUa8+W!z0CFSDd z6hJ>vX6z(nddjz+mGy*oD4>~8r;+X>*(XwYva+(PBVqHV3bU)B&HY?wf{{f>Bm#OZ zq1hP!WCP1imrxNp0EdhMPC2P~V0^cwd0(Z367c&>%Pwg=4vM=_Fr-4pG^RS_?w?H3 zL|b)qbRi>QoL@&lN*xCj(;S)VmGKmYI(ktj=vH~LF~XkzXoKNphg0i0a{xCxC# zm_QVz4>?&MVQ_+`z`d>eD>gxK+l6=`A#LqBdx^wLblJ?z2MpVwBalbGJ&ysgNF=fl ztvH5QBoKp$jF(`ZzTRS_|P|l-`=~pE2 zh;$m2)ag5Q-CyogD-AqHG_8J|2RH@{ND2ECyoWp`qzPqZ*+Eygi|7uf zm9M&d8IYpK0RSHb?vls*uMp!I8{XOG#^8H*R39RL1HRjJ@4}fzZIP&sD{SXR^IRll z6~P48Q3zdnjU+%RG91X(H$?7xYh{eu>w_R(1>u=#`}XPuxx}zY!|t2U4jg2olR|ds znfu=x*hF+}q7+R{O@!X71@9zu0#gcET;k$F3I&IOuc-o@*V)-gWb%X8KbOD-K?qm@ zaFpa7(cgCS@bo3?URMR@FaXY^!tt1cgaD%;;h2>p0#DQ?_*i%b>rkiwGjQ_ArptnV zaQd0-4g?(6Roj4k($LYVph*Md5`P$JqTa+%IVD$D*?^_Ji5qPqK%4Agpi6+n@rNBJ zYPJhJgSO|Yfp9BoqjWQ_L$!)z&tJx6MZ-L-t*J4PhzTYN?)!yq7h!SnhbNLWfgrWf z_}fD`WTINkleYgo8y~eGC>B!>-?`77MiMhdze;_H!^ z0Wuf~4PV3313Q#qvthy@UL|VNuR`=3`KKo|>XzgkT(Y!|*hQ2ip-}kLt249u$*bo~9b> zelOFJZ?n5+U-E|!&xVGFvxjOUbFiM-#6ar0({Pk1MwhUadPDjroFYrA<2W`_REjOb*jI5ut`4G3Xyi zY$K!Go0joG2`5JY0YwU5n#+I6u^CWiP9%o11_^L6!J!_AEMe%NBy z&ZY0Kwn1v}O@~^$U&v?%1`>%rX}`7DL5%)lTo38Nar7|=2#|v}Sg0~YooIcZdt(u3 zFb&~oS6~MqoeX$)7r|l_IY?V#QWAA)YAO;A1^>K>sxj_AxV_@m2Ync`ud=ej()Eg; znV6bpBOwP5I|}RtgA^?2aa7dD4}X6OC2OU%&rfu;$18ekTU(2cL3)I+$8kQb#r4%s zYbkBy1?T4GjKadgh%NO$)|7)9lBDzS?6S$~wOrB@3#?SSBVSo`>Fmv$LNJfGVnhun z!%rr;1~$zvLi^2zNBH*k&`En}eA#*3&VkS_GBIg#FsI{?4G{D2@RbA~@tL3|C=ZUN7qP>qQeZKB7~#;oMUhB+pXQ&rfT9Ij`8=Tsa|Qk!O8|P+I$` z?qD20>P1XdKM2RPO3}~IH1vZIrri#Hp@z1u0nh~&K?XC?S)V!o+y^zeKUlK61P&vD zxLd$<@U#7>S0E?QE`rSvI>D~T`3p*5jTmWH(D|{(AIb?D`ow4{aufr3^mw!~#h%waKKURoq6jBONRkgCDQtdzpg1JZ zp=iY)3*{s!5S*9dibpR(4A`hDs1z;B=I^f?Mbl-Qqr^>UVfAyf&>D!ciNZ%is7xP~ z3Js|gtrH19#B=F#b?POZ?CtC-aU5UC-MY1$ID&R| zCfFmyYa7SHjU&T0ju}NfMqz2`CvIyi3w7qX*%0{~l`%b%O)IAx&~T zsC${PQXm*OI_+WJ6oZT_hN&@Ijmz)Bp`k3xu7a5zJ}+MI%_G^D4N|S8t=(pD3?YCC zhfAv-`zIxAJf^SlX*=H#}$+S#E|nt)`1SE+t7D#4l4ne2T@OO zH*#=qbtcpU`E7>o?(XHuwjqL7!I62!~DTnw!IMd}SDn5cXsgP7zX-zz3v;M8(u+cd~WG|0Gq%-AOTtkt=y5dV#XgCEjsg= z(82!g2K5dMDEB`siVY;xAH8$Ae|#Y*G6K=buP*K; z@DL=|5ZN-g7Nz6>3pBOnmslK5h-fnqw{gnCsOh;XjuEP%ZgJs+xdC_RcjnuWmVUfb z{qwE7@_95@Ly|hmx90KaFGU1hUldZx-2t@k@cyecnBMNXdW*3ZJfP8t@fXj?Eigk{r~xV_At>FFN`th7q=eF-(k&w0jdVx~2r3~U0s?}B#37{wR6s!D0Ed*8 zE~&fDJAUu@#`oTP|GF_m*=}^7XFqGMIp>;BjF!e-;>)y`F)%QQRaF#q;Cnd+2Bs-K zE?n($YX-tMTub%4iWnE@UvHZVQ{WDPi^?N+42&xl=--${vV~9JCZ31teI>kUY%EH0 z98Hc_jc|*`L+PQ1g0rKejgtq4f}4$nhmAF}_Y)60=DVu*wH}0!P+?#&POB=)>G@1- zO!;~Yk4$xM_phg9trLduBuSHAJqUlM?vSg4iK+dlnwbmd(v{ExMnmmlJWL8b(ew{m zm$Yx($fZ;yVTrK3+NyX*eymbcNR^|<+E(ZmYAI3XSo$|+nff#4oKXphyCE*-K1;u+ zPY^ArB1OeJ9@sj&?95&29X>JC{DP(||8cc__22jYxr$4V{_j_ojf(%=`}fs6`+rZ#j}2_oj=y<*+1X8KKE7qUzMYBj7yh%5;y8U*yXdr*SvY z^wyX2TIyh)H{ZSVFBm7e5CjtRB+DKRB*gp3i5CrqEwb|kC0&bda%Bc)`#utmZ%I&c zE{G}P3hgDcYLlLk%oi>bcVvAP^^5gJ+3qDY4zDQNBs410`>y!$|DooeN*%)2psT}J z6DAZ$X!L03YZc$QO6Bkmq^9Zoyq~G3UgR&TyKF?`8yXoQ9krj-OfWT?u(OOh8m$>- z4catj2~WO%&%tBXOs}M*gilDQpr=P3NkkKB+T_>P*SFRZnLB9r5t)OUb-7bM>b}r4 z-aLYI5UsARHXr?H;xivFHse-5FgZyS)gJQE1TnYW&D8x)HD#bcJzYbrp+=CJC{uLO z!QS3}Yc`6>a&x+Atk#)nb!{yzM_paLeZ1=NC-XKeae9(_uZ0QP+S;;2XMRLd-TYYD z*eDgpB+E#}XZ%d9pka=orl+T;sJy)UYclKh>27~J3YD|%Ry+H*ufIR4$2zpl{EoFX z+n%3vV^dSEK}qh=3I;|B$NkVw%eHK3|D^PE?{>4#HjOPwN)rhTx6NyjgFkoLo zi-=Gp%ASjdhJ^|GY?&|b`{_M+pr8mZ6qj||`-^Q=;L^*CXct7>wrSw~`}f5I|5gjV zpe4fPF|H%^p7!Mo2nZ1HKX3?-h_KjS9dQw-FZ%eg>qpjY?FSDIvqB{4Nt!F-4p(mn z90}axNVz&!VbPwHk`l%!?bmAgX=ZsaUqwU1;2;?DZDS+-+GzP*clTWiY*E;=E4QXg z%JcHDoNDQ4<8ke4XlZC@239=qFJBHVEaZ%hjTP`(f9T`ykBw1n$eXFbX;5Yu;lA|4 zq{`?k4Zlg3gJ}DPSH4lL6FxDqqgeX)uU}hd+oO_GQ^UiU1jpx3Wy$2PodRx4a)gohT^YLiQc|^Kd5RGls z@rU?q)cM7)Uj_iI>d&9QEV>0QQN^hhtZsGZ3QcQp@bVJ-H8I-Q*k~2&6%`d}DgXLB zC?+kuJw4rQG9)dwC!=1v$)|N$5lGZG6pJHcc=dDh$macBt%#69s@M|$=MiM3&qQaq=WY)VZ zVq%AtzD_|wGEOaLUYBriZnB~@862}T3f(%(>+5OQ+1ZOqN)#SFqHz$VYd-!>M@~*Y z^9Qlnl_}w#>L}IapAr)t-O8FM70Q_ta5X+Ye!#w_*Gc}3To~?k*!kn*;|jyF=)}bC zdiNzQGqdtb>t2XYo@)k^{+ms(XGeo=SQox(_1|q3o;R8;%uC>3Cg zTG~%|*j{APNlZC`o`8udM0or)2l93AJMp0Q=ghpXlkF~t1DdT&MtjlR?o+g{qN6tQMJG2iGUc8k2 zrg0xWa5+rYky&*oIC|G1a&s}maEawrRS6nA*CKD~zMqMpGQH#OUbXYo(#k41IXPt1 zEZ9V%`g|j~hF72#84vh6-7gPTl9R(MHQ@eGQesgxo|KUh9UYCI`tqfGnE@*o*JT+Q z8F9A-eE0`1Qc_%(2d-y|yJAftyt`kEJQZ*ltI+r)e)6$gr=b^UtN?lp>kfxT=8gUR z{W&iL^6YizbE@aHwY3;YxBt{B5aEVlXvtI?maR`A9?+9S?bP$7tHb9OeEOvQ`puhy z&z}vTnXUg!*3Zq(<_0)9IFw$xbSb*coK#a&Q@dCX>(1%vY3hZBs%kP6SXE0aX~)V0 z;g$B~i@d937Q>EY-PE7H^J!UVE#6EK-FCD7Lp(4G1nDm=OvBAP1Cy07OkWMH!SRxwr_ddz~CI*61B*jM#gu{USa; zKL>UeHZ(L$ElwD;TL|5-P0h~!I2nj=M#+#jZ^QmHvrLL_OtKhs^xeC6Gq9^b)ypF#RMUQIylkADwS;vwH55jl z9pnJn&8Iu+ii(P@eSL(sRWxQn$Lw5OTyG6Z_z_s|VMoi1#Ecs}il-bEf%M@E*dKOX zB76M6$_v3D`i2+?s&4nkZ9%_1yLW|!R&Aj;WA*Nwkt7VU_uq(K7ZBL;&v!t`dzVe$ zi(uUpS#YaQ4Sq-_2XtfGpB=y0m(F_qdhS%9BZ#BCy*(H7qU&4-fz(zj_E^nRss``P zgw<7hG-o1_bQ*=%;EOBmGAx3M-!wciF|jfQ)Rl~yx+s8+o&7o++a;(Cx|UE6ug&Rr zpiJi5x9M&@{t<3i)|Glw*9A%rPh(+b#xN+Mz{JEv(b*u`tu*L@LIBt<7iWj_X%9^0 zbak(Rj*&1*MWdUz`Q%Ug(e^wUB_%F&0l*h_^{q3i`RD|7k+8eekH*AOe@>KXdDNht zBC0tM*5o?-1qal7Z+Q?KJVUE<&@SEH$`Bq@4ee>HtrsYm3|LrhaB;~yIq@}ktb{Hs zSo0WG%oON_WA^hMvop4!_F zfZ5XS2lyqBI&B@Dyvb}~^Hz+E@3zCgez6D&l7S0QvbD91k`e4)@i5&cy*j_q z0q=-kG7>vHtoJQjnodyN!^r_HAv#ETh{>iAz;zQ9hB|tZv6cDb7p=% zEHjfH{Zn@K#mc^Kj;yc2VUO5HfGC-mFsP}kZyzt^Six4^;N^vzx|ANKrltbaL|a>1 zcLD;W^78YO!9@X3>BU_zmVRWlmp-Zz@K_!o$?EqS-t3%;d|I?oS_%&=FXsot5rxMT zK_QjUFiHz|B16pW+LgDJ`>u>P$<89^O<$ilDLP$nN zcH#ME-SE3BjWg$~liy2A^SM!sI!-@{2nlr=eOFz?Ny*4CWo2c-mCYQsTu8I9u%z;e z0Oo~7MA|GrwOR|!4&*8vfvHLce^iSsGmf)!bkzUj1HJ`x6BY@7!lpb^&etZ{q$a|> zgokIfKK3a?zyfP-e!g71;ey-?arPlI(Y$dqW5m8Ql9+Dmr#gRbX(_?_V z7^q@LcQ-2!4-r_%PVgwHgB1XH@QxAb=~Pbji|RDZFUyZ+1VK^L_Wyz`1m+@J9z~K?9k9qfRP{o2;GOx&CRm@@0tv#o$;K`0#LQe zwMgRUouOq$wU&c+f#ILsc=I#s`K5452>$SyGF*ul-SYH!JY6n zC@83*&7^>b*5?AkT#;Nak+lM|Ex zYL#Y_n0z1L>(VcM_!ep)?YGwo^r>xXngBlOIyf2v0s??UsGCZmqntNbwm5o;tH5Dh zu@u|__QN-z6D^kqa>X1=GewQtT@E*pQ4xexdBw#9Ab&ofjIMtsC15VfZ)l*sW&5qQ z&UK#e`5*|`+24HyKR-z*wSfEYd+!PguHU+~`6XI1Y$+O!lo)=#yVE7z zwpD0m0@{xP22oSHjBeimSQOeNmzy>Tz}SY-3fAoH(29W5q6=m z!Si3;la%yU>LiYpf2on7*~IqK!>#ehITiqY=#GP zWd_ed$Xe}$StKNAVEo)VI8cT{Yvjlf!{$3oH`3J9)PP}WMLM^{0|Tu6^)iS%q>{W} zR9f0$@igoKyJ zyGwnQHhtEMy=iDW2QrX8<#OCfWu^iM1?*{p@dQ($Y8tSu6cZCe)?~_$8zxs-Rkb*u zC`*Z$`a$*gviQ;&4R|LlW8*kjYyR7}ck1!hXWGJG!cl$jXeZX2is@UJmJOu z4XVhILhwe^@e6FemWfGOrX#hO6Fqba%HlCmojEJUg+zYE(@{R2N0o}cw|^Nq)#E(= zk=X_4fklCnslTXV*IA zjfy8@RR$4F@^8r8^_u+h&Aw(X?21e)us>R1i;8ZPnl{mbN_8G=Aj!zd!{g$Jz|A?J zni-(iFrLB3pt%UhvOeoHMN>u&(1eED@W_Z|avO&2i?~^A_@<#001qHQX*KI(tGM9E@Bp7O8ceztQx>X{tF!33d83@zH zTie+503Hi!YW6Gp$Lrk-_co9ZK0A!(N!@&(mnRP%=|+h`*$dcBrD^|7>0=mYc)=lp zE-k>{(WulCx8e>9-Nos3^!3?cDtwWZRVEcn@JvxzSBdBj z5b$$xX(@Rvk{70c%E$eTF^P%kOWFP!eusZ}Y2%e)fMMg{=(S3e<^TnKaB9gc^JfLG z|0x|UE!r)WnzbtdP4^aRqEp4nf zDv*j!)ZrP(3QV_rrj7XNeFc+qyL&^LR$r5@%PyCeffInhr?~vHtB6a)MmcB`nie0{ zyRm~OPt6&!6JAEOv{W*Py3Q$1y7xt?g0op03Bds^1L^vsU_SN5+^9D49j|d;7~b;Ng$^9pl2$d3~}`I_P)r-peDe_ zCrwjhhu4QW2Ml~4yicdKP|sbaK(^XxzY>p)34L@S+arlBgKvei3a{x zxi~*72);P)9imZ?mtTO9G^wLQalFnof6PJjoYm#W$vgn2XS&JX2Dkulm3BAo^LOVF z`x>ZCFEo>NM>N?Eyql`Fc5R;yG4e9n)Tz~W(% zg|wMJYiW^%p`DoppM<1qXR&Xv+)Ngx;W;42u?A0Wc+u@KtHfN`IiKIJ9#;e$yBRn7 zkl}`5rt_J60k<$PF>x6&mGJYY4lw@F-@lfW`0u?5}tC$;EMhuzdL_D+dQIP%k=R7#tXQ z1|gIsgpFer7T6%?lspeHnoJYXELBv54`W|+LV~ipyE_6e5R$EbMJ4bOWTd2TCwqff z`;E%GhpszM_`G@jTI0HF)W?t;owz>u3K`V`WM^r0b>ip>!7L4vNu|e%4q!1Fq~{I@0Vkv(KS7Dc zKUqaVTym3#Clyp(&D#2%)bT=!j)4IOWCxQ@wcuUVpoEJMoh8BZ2(DbA05J38TKaHpd<|plJDN&-2xzZ$nDmrn~Y%mwC;+d z5wiYD>bu!=II)2du-!@Z6F`856eP6Vn4=>js{Ps0o$c)kT?q`_+uPfDgLbJto|0MU z!O`;5!-sV9XWI~au>nJl%c($G0iFIJ_WAQgFd`ct?O=ooUg`y>YX&Cm2K3eWQMas` zl2Qa(8z7gkK_h-SKT%CyK6FPz2KWq|DhCAx#pM0E%R$?ZH(-%l=`E)?kdF0+$^G45 z!vmKrb+TUNvygljEn1P0xacT^PdLB`9LY;QlUS#zhFQ?Sjz0dDxD8~jLiwoG(blY; zy*=2%v>p1W(o!A}j`vf@8i>qg$1()1(9Z$MAg82+#4z{$dt5N^kmp8%?{ISy`qQw+ zcY09Uq6ARD!p2T3v3gKxH^_oc&S5NvQ62J=FyuzppDDy3^5&D=Q73H(gKz!b7%Zif|-|}?{k7X@HiJ4Qa5v05vCJi2B@ye_rAt6_( zs5oJy$GQVb1j{so5(bkYE<4`lGOqB%Le)}pb8)=@Qx2r_A}NVEH#hexBO_mV)4}V9 zJe018DIF6NUT{(1gqgr}CJzq}dv&wv>gw76C$?m;#xtBHq{SU_8P>ZMz|iv*@^I^( z7wkVF4g^po_sg8zgHX)|;D{zM$Rn>ZFiib9ReTh&e0!_=v++L%`!^B75Toe&0*pb|~-1WB=r-Z`7N$AZV87 zr^lpZjbPq;ExBc7nbcqMXlIKDt^8yMj*iC1!ou2Guj;o1HE)T=6LoL%3Nvc*tMT#m zRW&xww5yr$O809y8!S+#@;zQmhvG%>Pk6Q>pM6A6fv{}IG93@Q*dSykiNeO1Sy_nz zBAkig%${K&&J^|du&E5n6bexm%&2{f^5*7mg?R1!H=`xoe+w9QA?x)F3_kl8nZS_- zYz20D9}W;6j2{-`l{Qk~DESETny0Y-3s5nqDy*AAaxL9pWDx|WS%@8B5Wyu`gtxg!}4Z%qkWJ_*1%um5+>eJPwS t^s(=Mowfe2uKs-h{C{x%y1aDERJh?lYCP@n8jiy;RFyOoKgyej{tt9Yrb7S# literal 0 HcmV?d00001 diff --git a/companion/src/wizarddialog.cpp b/companion/src/wizarddialog.cpp index 996e455c6..2ee125709 100644 --- a/companion/src/wizarddialog.cpp +++ b/companion/src/wizarddialog.cpp @@ -1,6 +1,47 @@ #include #include "wizarddialog.h" +Channel::Channel() +{ + clear(); +} + +void Channel::clear() +{ + sourceDlg = -1; + input1 = UNDEFINED; + input2 = UNDEFINED; + weight1 = 0; + weight2 = 0; +} + +bool Channel::isEmpty() +{ + return sourceDlg < 0; +} + +QString Channel::nameOf(Input input) +{ + switch (input){ + case THROTTLE: return "THR"; + case RUDDER: return "RUD"; + case ELEVATOR: return "ELE"; + case AILERON: return "AIL"; + case FLAP: return "FLP"; + case AIRBREAK: return "AIR"; + default: return "---"; + } +} + +QString Channel::print() +{ + QString str; + str = QString("[%1, %2]").arg(nameOf(input1)).arg(weight1); + if ( input2 != UNDEFINED ) + str += QString("[%1, %2]").arg(nameOf(input2)).arg(weight2); + return str; +} + WizardDialog::WizardDialog(QWidget *parent) : QWizard(parent) { @@ -16,6 +57,7 @@ WizardDialog::WizardDialog(QWidget *parent) setPage(Page_Rudder, new RudderPage(this, "rudder",tr("Rudder"),tr("Does your model have a rudder?"), Page_Conclusion)); setPage(Page_Tails, new TailSelectionPage(this, "tails",tr("Tail Type"),tr("Select which type of tail your model is equiped with."))); setPage(Page_Tail, new TailPage(this, "tail",tr("Tail"),tr("Select channels for tail control."), Page_Conclusion)); + setPage(Page_Vtail, new VTailPage(this, "vtail",tr("V-Tail"),tr("Select channels for tail control."), Page_Conclusion)); setPage(Page_Simpletail, new SimpleTailPage(this, "simpletail",tr("Tail"),tr("Select elevator channel."), Page_Conclusion)); setPage(Page_Cyclic, new CyclicPage(this, "cyclic",tr("Cyclic"),tr("Which type of swash control is installed in your helicopter?"), Page_Gyro)); setPage(Page_Gyro, new GyroPage(this, "gyro",tr("Tail Gyro"),tr("Has your helicopter got an adjustable gyro for the tail?"), Page_Flybar)); @@ -24,10 +66,9 @@ WizardDialog::WizardDialog(QWidget *parent) setPage(Page_Helictrl, new HeliPage(this, "helictrl",tr("Helicopter"),tr("Select the controls for your helicopter"), Page_Conclusion)); setPage(Page_Multirotor, new MultirotorPage(this, "multirotor",tr("Multirotor"),tr("Select the control channels for your multirotor"), Page_Conclusion)); setPage(Page_Conclusion, new ConclusionPage(this, "conclusion",tr("Save Changes"),tr( - "Your model should now be set up. You now have to manually check the direction of each control surface and reverse the channels that " - "make controls move in the wrong direction.

Remove the propeller/propellers before you try to control your model for the first time.

" + "Manually check the direction of each control surface and reverse any channels that make controls move in the wrong direction. " + "Remove the propeller/propellers before you try to control your model for the first time.
" "Please note that continuing removes all old model settings!"), -1)); - setStartId(Page_Models); #ifndef Q_WS_MAC @@ -58,6 +99,7 @@ void WizardDialog::showHelp() case Page_Rudder: message = tr("TBD."); break; case Page_Tails: message = tr("Select the tail type of your plane."); break; case Page_Tail: message = tr("TBD."); break; + case Page_Vtail: message = tr("TBD."); break; case Page_Simpletail: message = tr("TBD."); break; case Page_Flybar: message = tr("TBD."); break; case Page_Cyclic: message = tr("TBD."); break; @@ -65,17 +107,18 @@ void WizardDialog::showHelp() case Page_Fblheli: message = tr("TBD."); break; case Page_Helictrl: message = tr("TBD."); break; case Page_Multirotor: message = tr("TBD."); break; - case Page_Conclusion: message = tr("TBD."); break; + case Page_Conclusion: message = tr("TBD."); break; default: message = tr("Move on. Nothin to see here."); } QMessageBox::information(this, tr("Model Wizard Help"), message); } -StandardPage::StandardPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) +StandardPage::StandardPage(int currentPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage ) : QWizardPage() { + pageCurrent = currentPage; pageFollower = nextPage; - wizardDialog = dlg; + wizDlg = dlg; setTitle(title); setPixmap(QWizard::WatermarkPixmap, QPixmap(QString(":/images/wizard/") + image + QString(".png"))); @@ -87,13 +130,59 @@ StandardPage::StandardPage(WizardDialog *dlg, QString image, QString title, QStr setLayout(layout); } +void StandardPage::populateCB( QComboBox *CB ) +{ + for (int j=0; jremoveItem(0); + + for (int i=0; ichannel[i].isEmpty()){ + CB->addItem(tr("Channel ") + QString("%1").arg(i+1), i); + } + } +} + +bool StandardPage::bookChannel(QString label, Input input1, int weight1, Input input2, int weight2 ) +{ + int index = label.right(1).toInt() - 1; + + if (index<0 || index >= MAX_CHANNELS) + return false; + if (!wizDlg->channel[index].isEmpty()) + return false; + + wizDlg->channel[index].sourceDlg = pageCurrent; + wizDlg->channel[index].input1 = input1; + wizDlg->channel[index].input2 = input2; + wizDlg->channel[index].weight1 = weight1; + wizDlg->channel[index].weight2 = weight2; + + return true; +} + +void StandardPage::releaseChannels() +{ + for (int i=0; ichannel[i].sourceDlg == pageCurrent){ + wizDlg->channel[i].clear(); + } + } +} + +void StandardPage::cleanupPage() +{ + releaseChannels(); +} + int StandardPage::nextId() const { return pageFollower; } ModelSelectionPage::ModelSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) - : StandardPage(dlg, image, title, text) + : StandardPage(WizardDialog::Page_Models, dlg, image, title, text) { nameLineEdit = new QLineEdit; planeRB = new QRadioButton(tr("Plane")); @@ -124,7 +213,7 @@ int ModelSelectionPage::nextId() const } WingtypeSelectionPage::WingtypeSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) - : StandardPage(dlg, image, title, text) + : StandardPage(WizardDialog::Page_Wingtypes, dlg, image, title, text) { standardWingRB = new QRadioButton(tr("Standard Wing")); standardWingRB->setChecked(true); @@ -144,7 +233,7 @@ int WingtypeSelectionPage::nextId() const } TailSelectionPage::TailSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) - : StandardPage(dlg, image, title, text) + : StandardPage(WizardDialog::Page_Tails, dlg, image, title, text) { standardTailRB = new QRadioButton(tr("Elevator and Rudder")); standardTailRB->setChecked(true); @@ -162,12 +251,14 @@ int TailSelectionPage::nextId() const { if (simpleTailRB->isChecked()) return WizardDialog::Page_Simpletail; + else if (vTailRB->isChecked()) + return WizardDialog::Page_Vtail; else return WizardDialog::Page_Tail; } FlybarSelectionPage::FlybarSelectionPage(WizardDialog *dlg, QString image, QString title, QString text) - : StandardPage(dlg, image, title, text) + : StandardPage(WizardDialog::Page_Flybar, dlg, image, title, text) { flybarRB = new QRadioButton(tr("Has Flybar")); flybarRB->setChecked(true); @@ -188,7 +279,7 @@ int FlybarSelectionPage::nextId() const } ThrottlePage::ThrottlePage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Throttle, dlg, image, title, text, nextPage) { motorRB = new QRadioButton(tr("Yes")); noMotorRB = new QRadioButton(tr("No")); @@ -202,8 +293,17 @@ ThrottlePage::ThrottlePage(WizardDialog *dlg, QString image, QString title, QStr l->addWidget(throttleCB); } +void ThrottlePage::initializePage(){ + populateCB(throttleCB); +} + +bool ThrottlePage::validatePage() { + releaseChannels(); + return bookChannel(throttleCB->currentText(), THROTTLE, 100 ); +} + AileronsPage::AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Ailerons, dlg, image, title, text, nextPage) { noAileronsRB = new QRadioButton(tr("No")); oneAileronRB = new QRadioButton(tr("Yes, controlled by a single channel")); @@ -222,8 +322,25 @@ AileronsPage::AileronsPage(WizardDialog *dlg, QString image, QString title, QStr l->addWidget(aileron2CB); } +void AileronsPage::initializePage(){ + populateCB(aileron1CB); + populateCB(aileron2CB); +} + +bool AileronsPage::validatePage() { + releaseChannels(); + if (noAileronsRB->isChecked()) { + return true; + } + if (oneAileronRB->isChecked()) { + return (bookChannel(aileron1CB->currentText(), AILERON, 100 )); + } + return( bookChannel(aileron1CB->currentText(), AILERON, 100 ) && + bookChannel(aileron2CB->currentText(), AILERON, 100 )); +} + FlapsPage::FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Flaps, dlg, image, title, text, nextPage) { noFlapsRB = new QRadioButton(tr("No")); oneFlapRB = new QRadioButton(tr("Yes, controlled by a single channel")); @@ -242,8 +359,25 @@ FlapsPage::FlapsPage(WizardDialog *dlg, QString image, QString title, QString te l->addWidget(flap2CB); } +void FlapsPage::initializePage(){ + populateCB(flap1CB); + populateCB(flap2CB); +} + +bool FlapsPage::validatePage() { + releaseChannels(); + if (noFlapsRB->isChecked()) { + return true; + } + if (oneFlapRB->isChecked()) { + return (bookChannel(flap1CB->currentText(), FLAP, 100 )); + } + return( bookChannel(flap1CB->currentText(), FLAP, 100 ) && + bookChannel(flap2CB->currentText(), FLAP, 100 )); +} + AirbreaksPage::AirbreaksPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Airbrakes, dlg, image, title, text, nextPage) { noAirbreaksRB = new QRadioButton(tr("No")); oneAirbreakRB = new QRadioButton(tr("Yes, controlled by a single channel")); @@ -262,8 +396,25 @@ AirbreaksPage::AirbreaksPage(WizardDialog *dlg, QString image, QString title, QS l->addWidget(airbreak2CB); } +void AirbreaksPage::initializePage(){ + populateCB(airbreak1CB); + populateCB(airbreak2CB); +} + +bool AirbreaksPage::validatePage() { + releaseChannels(); + if (noAirbreaksRB->isChecked()) { + return true; + } + if (oneAirbreakRB->isChecked()) { + return (bookChannel(airbreak1CB->currentText(), AIRBREAK, 100 )); + } + return( bookChannel(airbreak1CB->currentText(), AIRBREAK, 100 ) && + bookChannel(airbreak2CB->currentText(), AIRBREAK, 100 )); +} + BankPage::BankPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Bank, dlg, image, title, text, nextPage) { oneElevonChRB = new QRadioButton(tr("One")); oneElevonChRB->setChecked(true); @@ -279,8 +430,23 @@ BankPage::BankPage(WizardDialog *dlg, QString image, QString title, QString text l->addWidget(new QLabel(tr("Second Elevon Channel:"))); l->addWidget(elevon2CB); } + +void BankPage::initializePage(){ + populateCB(elevon1CB); + populateCB(elevon2CB); +} + +bool BankPage::validatePage() { + releaseChannels(); + if (oneElevonChRB->isChecked()) { + return (bookChannel(elevon1CB->currentText(), AILERON, 100, ELEVATOR, 100 )); + } + return( bookChannel(elevon1CB->currentText(), AILERON, 100, ELEVATOR, 100 ) && + bookChannel(elevon2CB->currentText(), AILERON, 100, ELEVATOR, 100 )); +} + RudderPage::RudderPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Rudder, dlg, image, title, text, nextPage) { noRudderRB = new QRadioButton(tr("No")); noRudderRB->setChecked(true); @@ -294,8 +460,44 @@ RudderPage::RudderPage(WizardDialog *dlg, QString image, QString title, QString l->addWidget(rudderCB); } +void RudderPage::initializePage(){ + populateCB(rudderCB); +} + +bool RudderPage::validatePage() { + releaseChannels(); + if (noRudderRB->isChecked()) + return true; + + return (bookChannel(rudderCB->currentText(), RUDDER, 100)); +} + +VTailPage::VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) + : StandardPage(WizardDialog::Page_Tail, dlg, image, title, text, nextPage) +{ + tail1CB = new QComboBox(); + tail2CB = new QComboBox(); + + QLayout *l = layout(); + l->addWidget(new QLabel(tr("First Tail Channel:"))); + l->addWidget(tail1CB); + l->addWidget(new QLabel(tr("Second Tail Channel:"))); + l->addWidget(tail2CB); +} + +void VTailPage::initializePage(){ + populateCB(tail1CB); + populateCB(tail2CB); +} + +bool VTailPage::validatePage() { + releaseChannels(); + return( bookChannel(tail1CB->currentText(), ELEVATOR, 100, RUDDER, 100 ) && + bookChannel(tail2CB->currentText(), ELEVATOR, 100, RUDDER, 100 )); +} + TailPage::TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Tail, dlg, image, title, text, nextPage) { elevatorCB = new QComboBox(); rudderCB = new QComboBox(); @@ -307,8 +509,19 @@ TailPage::TailPage(WizardDialog *dlg, QString image, QString title, QString text l->addWidget(elevatorCB); } +void TailPage::initializePage(){ + populateCB(elevatorCB); + populateCB(rudderCB); +} + +bool TailPage::validatePage() { + releaseChannels(); + return( bookChannel(elevatorCB->currentText(), ELEVATOR, 100 ) && + bookChannel(rudderCB->currentText(), RUDDER, 100 )); +} + SimpleTailPage::SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Simpletail, dlg, image, title, text, nextPage) { elevatorCB = new QComboBox(); @@ -317,8 +530,17 @@ SimpleTailPage::SimpleTailPage(WizardDialog *dlg, QString image, QString title, l->addWidget(elevatorCB); } +void SimpleTailPage::initializePage(){ + populateCB(elevatorCB); +} + +bool SimpleTailPage::validatePage() { + releaseChannels(); + return( bookChannel(elevatorCB->currentText(), ELEVATOR, 100 )); +} + CyclicPage::CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Cyclic, dlg, image, title, text, nextPage) { cyclic90RB = new QRadioButton(tr("90")); cyclic90RB->setChecked(true); @@ -333,8 +555,16 @@ CyclicPage::CyclicPage(WizardDialog *dlg, QString image, QString title, QString l->addWidget(cyclic140RB); } +void CyclicPage::initializePage(){ +} + +bool CyclicPage::validatePage() { + releaseChannels(); + return true; +} + GyroPage::GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Gyro, dlg, image, title, text, nextPage) { noGyroRB = new QRadioButton(tr("No")); noGyroRB->setChecked(true); @@ -347,8 +577,16 @@ GyroPage::GyroPage(WizardDialog *dlg, QString image, QString title, QString text l->addWidget(potGyroRB); } +void GyroPage::initializePage(){ +} + +bool GyroPage::validatePage() { + releaseChannels(); + return true; +} + FblPage::FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Fblheli, dlg, image, title, text, nextPage) { throttleCB = new QComboBox(); yawCB = new QComboBox(); @@ -366,8 +604,23 @@ FblPage::FblPage(WizardDialog *dlg, QString image, QString title, QString text, l->addWidget(rollCB); } +void FblPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool FblPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB->currentText(), THROTTLE, 100 ) && + bookChannel(yawCB->currentText(), RUDDER, 100 ) && + bookChannel(pitchCB->currentText(), ELEVATOR, 100 ) && + bookChannel(rollCB->currentText(), AILERON, 100 )); +} + HeliPage::HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Helictrl, dlg, image, title, text, nextPage) { throttleCB = new QComboBox(); yawCB = new QComboBox(); @@ -385,8 +638,23 @@ HeliPage::HeliPage(WizardDialog *dlg, QString image, QString title, QString text l->addWidget(rollCB); } +void HeliPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool HeliPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB->currentText(), THROTTLE, 100 ) && + bookChannel(yawCB->currentText(), RUDDER, 100 ) && + bookChannel(pitchCB->currentText(), ELEVATOR, 100 ) && + bookChannel(rollCB->currentText(), AILERON, 100 )); +} + MultirotorPage::MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Multirotor, dlg, image, title, text, nextPage) { throttleCB = new QComboBox(); yawCB = new QComboBox(); @@ -404,13 +672,43 @@ MultirotorPage::MultirotorPage(WizardDialog *dlg, QString image, QString title, l->addWidget(rollCB); } +void MultirotorPage::initializePage(){ + populateCB(throttleCB); + populateCB(yawCB); + populateCB(pitchCB); + populateCB(rollCB); +} + +bool MultirotorPage::validatePage() { + releaseChannels(); + return( bookChannel(throttleCB->currentText(), THROTTLE, 100 ) && + bookChannel(yawCB->currentText(), RUDDER, 100 ) && + bookChannel(pitchCB->currentText(), ELEVATOR, 100 ) && + bookChannel(rollCB->currentText(), AILERON, 100 )); +} + ConclusionPage::ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage) - : StandardPage(dlg, image, title, text, nextPage) + : StandardPage(WizardDialog::Page_Conclusion, dlg, image, title, text, nextPage) { + textLabel = new QLabel(); proceedCB = new QCheckBox(tr("OK, I understand.")); registerField("evaluate.proceed*", proceedCB); QLayout *l = layout(); + l->addWidget(textLabel); l->addWidget(proceedCB); } +void ConclusionPage::initializePage(){ + QString str; + for (int i=0; ichannel[i].isEmpty()){ + str += QString(tr("Channel %1: ").arg(i+1)); + str += wizDlg->channel[i].print(); + str += QString("
"); + } + } + textLabel->setText(str); +} + + diff --git a/companion/src/wizarddialog.h b/companion/src/wizarddialog.h index 09a80c72f..36e52275e 100644 --- a/companion/src/wizarddialog.h +++ b/companion/src/wizarddialog.h @@ -12,17 +12,38 @@ class QComboBox; QT_END_NAMESPACE +#define MAX_CHANNELS 8 + +enum Input {UNDEFINED, THROTTLE, RUDDER, ELEVATOR, AILERON, FLAP, AIRBREAK}; + +class Channel +{ +public: + int sourceDlg; + Input input1; + Input input2; + int weight1; + int weight2; + + Channel(); + QString nameOf(Input); + bool isEmpty(); + void clear(); + QString print(); +}; + + class WizardDialog : public QWizard { Q_OBJECT - public: enum { Page_Models, Page_Throttle, Page_Wingtypes, Page_Ailerons, Page_Flaps, Page_Airbrakes, Page_Bank, Page_Rudder, Page_Tails, Page_Tail, - Page_Simpletail, Page_Cyclic, Page_Gyro, Page_Flybar, + Page_Vtail, Page_Simpletail, Page_Cyclic, Page_Gyro, Page_Flybar, Page_Fblheli, Page_Helictrl, Page_Multirotor, Page_Conclusion }; + Channel channel[MAX_CHANNELS]; WizardDialog(QWidget *parent = 0); private slots: @@ -33,10 +54,15 @@ class StandardPage: public QWizardPage { Q_OBJECT public: - StandardPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); - WizardDialog *wizardDialog; + StandardPage(int curPage, WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + WizardDialog *wizDlg; + void populateCB( QComboBox *); + bool bookChannel(QString label, Input input1, int weight1, Input input2=UNDEFINED, int weight2=0 ); + void releaseChannels(); + void cleanupPage(); private: QLabel *topLabel; + int pageCurrent; int pageFollower; int nextId() const; }; @@ -93,6 +119,8 @@ class ThrottlePage: public StandardPage Q_OBJECT public: ThrottlePage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *motorRB; QRadioButton *noMotorRB; @@ -104,6 +132,8 @@ class AileronsPage: public StandardPage Q_OBJECT public: AileronsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *oneAileronRB; QRadioButton *twoAileronsRB; @@ -117,6 +147,8 @@ class FlapsPage: public StandardPage Q_OBJECT public: FlapsPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *oneFlapRB; QRadioButton *twoFlapsRB; @@ -130,6 +162,8 @@ class AirbreaksPage: public StandardPage Q_OBJECT public: AirbreaksPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *oneAirbreakRB; QRadioButton *twoAirbreaksRB; @@ -143,6 +177,8 @@ class BankPage: public StandardPage Q_OBJECT public: BankPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *oneElevonChRB; QRadioButton *twoElevonsChRB; @@ -155,6 +191,8 @@ class RudderPage: public StandardPage Q_OBJECT public: RudderPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *noRudderRB; QRadioButton *hasRudderRB; @@ -165,16 +203,34 @@ class TailPage: public StandardPage { Q_OBJECT public: - TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + TailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: QComboBox *elevatorCB; QComboBox *rudderCB; }; +class VTailPage: public StandardPage +{ + Q_OBJECT +public: + VTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: + QComboBox *tail1CB; + QComboBox *tail2CB; +}; + class SimpleTailPage: public StandardPage { Q_OBJECT public: - SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + SimpleTailPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); +private: QComboBox *elevatorCB; }; @@ -183,6 +239,8 @@ class CyclicPage: public StandardPage Q_OBJECT public: CyclicPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *cyclic90RB; QRadioButton *cyclic120RB; @@ -195,6 +253,8 @@ class GyroPage: public StandardPage Q_OBJECT public: GyroPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QRadioButton *noGyroRB; QRadioButton *switchGyroRB; @@ -205,7 +265,9 @@ class FblPage: public StandardPage { Q_OBJECT public: - FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + FblPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QComboBox *throttleCB; QComboBox *yawCB; @@ -217,7 +279,9 @@ class HeliPage: public StandardPage { Q_OBJECT public: - HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + HeliPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QComboBox *throttleCB; QComboBox *yawCB; @@ -229,7 +293,9 @@ class MultirotorPage: public StandardPage { Q_OBJECT public: - MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + MultirotorPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); + bool validatePage(); private: QComboBox *throttleCB; QComboBox *yawCB; @@ -241,9 +307,11 @@ class ConclusionPage: public StandardPage { Q_OBJECT public: - ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + ConclusionPage(WizardDialog *dlg, QString image, QString title, QString text, int nextPage=-1); + void initializePage(); private: QCheckBox *proceedCB; + QLabel *textLabel; }; #endif // WIZARDDIALOG_H