From 33fdfcc0ace46077fed213bdb1bde4ca1a869aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Tue, 15 Dec 2015 09:48:51 +0100 Subject: [PATCH] Debugger - display variables in the tree structure Set variables while debugging --- .gitignore | 5 +- lib/flashdebugger.jar | Bin 249501 -> 249247 bytes lib/treetable.jar | Bin 0 -> 26340 bytes libsrc/cmykjpeg/nbproject/build-impl.xml | 14 +- libsrc/cmykjpeg/nbproject/genfiles.properties | 4 +- libsrc/jpproxy/nbproject/build-impl.xml | 14 +- libsrc/jpproxy/nbproject/genfiles.properties | 4 +- libsrc/treetable/build.xml | 73 + libsrc/treetable/manifest.mf | 3 + libsrc/treetable/nbproject/build-impl.xml | 1419 +++++++++++++++++ .../treetable/nbproject/genfiles.properties | 8 + libsrc/treetable/nbproject/project.properties | 73 + libsrc/treetable/nbproject/project.xml | 15 + .../treetable/MyAbstractTreeTableModel.java | 91 ++ .../de/hameister/treetable/MyDataModel.java | 64 + .../de/hameister/treetable/MyDataNode.java | 56 + .../de/hameister/treetable/MyTreeTable.java | 51 + .../treetable/MyTreeTableCellEditor.java | 44 + .../treetable/MyTreeTableCellRenderer.java | 75 + .../hameister/treetable/MyTreeTableModel.java | 58 + .../treetable/MyTreeTableModelAdapter.java | 63 + .../treetable/MyTreeTableSelectionModel.java | 26 + .../de/hameister/treetable/TreeTableMain.java | 84 + nbproject/project.xml | 2 +- .../decompiler/flash/gui/DebugPanel.java | 106 +- .../decompiler/flash/gui/DebuggerHandler.java | 46 + src/com/jpexs/decompiler/flash/gui/Main.java | 8 +- .../decompiler/flash/gui/abc/ABCPanel.java | 361 ++++- 28 files changed, 2704 insertions(+), 63 deletions(-) create mode 100644 lib/treetable.jar create mode 100644 libsrc/treetable/build.xml create mode 100644 libsrc/treetable/manifest.mf create mode 100644 libsrc/treetable/nbproject/build-impl.xml create mode 100644 libsrc/treetable/nbproject/genfiles.properties create mode 100644 libsrc/treetable/nbproject/project.properties create mode 100644 libsrc/treetable/nbproject/project.xml create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyAbstractTreeTableModel.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyDataModel.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyDataNode.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellEditor.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellRenderer.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTableModel.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTableModelAdapter.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/MyTreeTableSelectionModel.java create mode 100644 libsrc/treetable/src/de/hameister/treetable/TreeTableMain.java diff --git a/.gitignore b/.gitignore index 613ec67bd..598439978 100644 --- a/.gitignore +++ b/.gitignore @@ -65,4 +65,7 @@ hs_err_pid*.log /libsrc/cmykjpeg/nbproject/private/ /libsrc/Plugins/nbproject/private/ /libsrc/Plugins/build/ -/libsrc/Plugins/dist/ \ No newline at end of file +/libsrc/Plugins/dist/ +/libsrc/treetable/nbproject/private/ +/libsrc/treetable/build/ +/libsrc/treetable/dist/ \ No newline at end of file diff --git a/lib/flashdebugger.jar b/lib/flashdebugger.jar index 8b7a7a60c7c407f4ea86707ecc72f5298aaab047..6f2c726d56043785f4b4e9dc49d454b66aa8f7d6 100644 GIT binary patch delta 14239 zcma)D2Y8f4^PhP)m-lixQb|am1!)O^gx*OIkq)8vK!8Yx6p$(*fb{+XORo_GA_O8i zAwWR7NKx?v5hpVBYtGr%z!w>PHQHi1`5c9nM1LVSu>H!<^!fmz#2C$IRyGQfJ&o_%`evN-f~i=>25(_m8{g9w?SR(pkqfJJL#BU zgNE2y$1XN#ES_C61Y|cIyW6k__OwA9_R_Jpj(v3Ot7AVKv=sjJ_kvcKsN(<|w84Qo zCV4?S9Hir5@f>1<4w$Ut8#YM5p*jw;K^GjZ;|Lpc!;w0U(s8s6dg2%_=z(Kxn1ZQR zOtZrG!gNNu6~|d|yrAC{ya`sEXvIlZoNUD@R-9_Zx2!nLiqg^PR?M{G3@gsG;w&q^ zZN=F-&apu%mbKzs@th|<=8KO7R$Qp#A{$H;owis6cZrTmbzFvE>6tWc@Gt~>n_T}6 zJrI{0!#d`pkz27-0^*9?@d@=cog`OMC*aYk0+RvJEmtz z#8J63dwqep*y!JJNAyr&&bgmM`r(Z>Hiyb$B!zkM?j%~zE#+`vu%4RI-=f&pX zW@BJ-6kl=~Z6vn^w+hVaeA;a0DPgv8T&zWLzbTqd{4B!xB&m|Iw6AWA>F-JE?+DL$ z>>15U?CrRN<25bXxY6H_c<&0A>Km04Ln`jXT@(a6?#668yblNL@BujN_#W=DL!O}a zVh$e|jX_?xkLqwg>?hz21d>Y*M;VK{+KnCq-lXsEJKJe9at2rp&w=&XcW_VE8n*}8 zjIjf4-UsZMhYk^j4|wK4j578N{FEIe%+6IR@z{4XKiRfJ)RtIsJD-9_F)eN6RP;0c zY2|6N!!=kfv=8%?d@Y*C#4x*6d_RKFkniirqItPytb_zPDlmm%KA<=A^bk@;^Zu0$ zzaAE2;NYem=HW3rJco~{+wFK98A8B>;X{%Kj2b>BdBBk5LF0!GO-{4JpYRugpNo?+ zDrr)38Uh>p#v68c3eW8LA!Zvt4u0PQ{zRLxbx4}Q28H?21abmTijPxvJdJ0Ju;i)i zEUq;+w~5X@m7Hra?u=~ht*4J4JUBT$9U;W1X%94(wAORK7!`?}mBd~~e6v6N(h2Pr?Hl5GH6n zdJ2!M!lOK3E=ZfyP5>P`7jew$bZik}XwtFQ$g03F>WwX3SF}f|c7q`3UPLw6R9#FG zLSYG&r3%EDGqy?*&0eJ0=U+6JnVNUqH2afg;=gDvH#Or@irP#f&B6boX}}7K^DJXs zO0x{n&H!o$z#G(OL!mMZqs|^75u&KRGFV_GtP=eK)ty~X9XPC(!Kw~xh|*v!@flz> zaD`O55d?nA2jg(_*k`(Pao> z3v3kzj035)`@7K6p)`z>XmzL+02Q2Q6=0j`e+9^r{tNCqL^0Cwgzd0{+FsPcyRegZ zvy7H$F`Zo&CPFAoD&lWhr-ibng;27*3wD!tE;JRGJrtO|kR$y*l~yUvg*puaDaFMo zQmJ3kiCPl&!G6+nVIkz2c@UXixk&EKq)5IkG1N#5GBJv3()=siG%LND%mX!k=N4&C znA38Yn4V>ihlwehygumkPw);od54N=Yd&!ggP8=_oUH1kJt-e5_jW*)j`?8J7&i{z zHnxq6$q?;sP5e600*+9RcnV3UACsJUFv-jVE2K)_82D4}3g0}SCLtV!0*Za1mrCjo zSyobqNJ`{vX<*OEl&-@uL>-Rn<*C4jG!Ha+Lh41sbplSx&Pp9$uf6CjIa$FvnkLrM z(Aij|!zwx5tpulJqM5_P?gn@o&dB)xKE76w_-~a!A_71Yv6?>xbyoJgpw7WZIdTPNas^g1`Bf-K zL9YT|Km!V>7*DG68aV^g2!1j#!g;2ubA^d6v#tQfp8tCvF zWE5@5@9>A&lG)S_k$6$6B?)Fr9MIX>3Xf0^YK6yU&^>5^W!WUH99Pl2MFww6hsDxE zNKS{NoDN69&l%F=aPXDhsc}pIPoXM#7wJOe+543YOmV?diW)5uUVB0LXQM!HEO)uJ8HJ)no|$sQeFwDkiWD}OA~ z=x}GF!)4NnElIdcRgEMOom zC!8w>CB$BrLLr8|H{dgf)RFSzdQrb=)EDl(>XVXas8>`#-++F3(Er6KJ*MIQr*y;) z8B)>=Q;|5JhRlpZ0~60DDj+dnKpqSfph+U%if&c^HUR~mPce8N#o-MK$oQXt&;JF` zQXJsm|LGt}i_xoAaF>G=e{5ei&2)+yCY67UwB5eP$E1 zm@E9Fs+C>?)_{IHz#@E>X~|Uk<&=dXgc~Yx)sD3gmvo)u!=IwGpOD2^s1Dk58W4#Df^vuCh_8Eu@{b(45()|-5M1zoJR797e)(~1|7>3X>H+gr|4iQQ3zKQ zZDet13J}YY>dy#fHz;BA+ZjGV%;L9itODf`^9OksHvdhOig&nRI!#a z8jz`m|8G;l&M9C$wMq=D>V9RLgl~i@YLS{K7byo!3YeS+Q;xyp4$-H<;*mWIpYM47 zWsyxn1#z*AO(26|Q;KUdD2H)$u^CTymajrpYys8qHR+WYisiryOVRKYQ7k;TGKiwV zDncQKqA#$gz-Utwp<|f)W?#c_63}QIiM1|_;5yKi$TZrjt*3EaVFMA_v~PS5yxeZQ zTb=#f@BTJg|F;=6=hn_mnfboDfUYw4p(4T-eOF7~X=m_?b$orv2VcIo7M3$o!mRw^ zdR8L$)nlQ)@@6{m(p;1m&BrI4h`JaHAWE$9iB_6#-oQ%bMt$<%$c%W3NJ(-u&d*xU zf{i=_HZ{_zSXn)-#V)l`0?@?6OY+5b-wx|&Z^9;|3& zGdBGl?#b#|cF;ZMk-tMiJp?&f@j`8lJU!}pSwz)Ph&x}y=T$>9dQ=Up|cC49VyV9{Hl@utZ~LL;5Z64;AqIkF|ZfM!hTGJ z12`V?aRLSsJ&f;{qgqiR)&VWZa6X|9bOVcH7Wn7LiXkcwzfempbwm^;@ z>Hf4QuEjTS9S+C!B)J*q;6|K>+ejmeYTm(j=|XdN2JXWBbZ>bIv+){TSU$i#_y^|T zbKIwCxL>nio@Pad=8Yd{zIadzz$02IJgS9ZfmRleX%To{tArnGk$6Fi#yhk*2lS(j z-5h!b(f}<1Z$bnHp)Z{$r_g17FqWcqVgp_ChtScFuJ!Ywgkob)sE(l+Mz00tk#aa? zX&}ZxADZ#c(rQ$j?!?Oyj6Zgy8~Jirp6+)p!3~Z{Lc7mZ1PLv-} z9^j!hrn&ws?JISy0d+tX+8=vsb+9UF=-{ixVkA*k2+*n<6P|bR_7&&DczgmS0*ouq zlQp}~%Enj?zg;;Lo8b>Dw_|hsY328rP~une_BRN^-=P#f;w=$-c>P7o{1bYi@|0&G zHWY)%aT{@}kE90p(Tf*J%`Sz}@^z5oKpFgk$+~3`IL1?swo_Gte(OrFutcdTM_W!Q z^y0qJ=;dfu6$jg-d{!-bEg>nNM%Xe`Qa!q2ElpAjy5l)T_3TBje`MX{0r;DIKjj#k zgohM2dI*+M+}B6qE>AfzB*x#W|20i>Ut4+VWL8yNAM%iN+C((>F$%7~5X;pc`N(|&F?=VkC+zOoOAzyi2 z{U>5EUzUdr_~mz435V|*JgvfVZ9UG{B}|1sQ%4V>E*_#u7{l*opksFyj?*M}blzWG zh7xzE#_yz3Pfow->lnTRC#YuL-H9#a^yi4&gPjyLWk32TYGEGwDQeRp+^#fQAHg_P zH~%;;(`3hNt3TSf?+qYIEskjz#c!QP3-5apeKR)c(A!4SdLJ8|8T$&VpB3m8lP@HS zF9WPFP<%=9hCwjc3PZ$~WGlQOn0<8^D%6Hqo|}JyJDlFa!3Z5j+QcQU_%cc;(`zSR z7$ZK$ijNc_n(D>BIf-HACcs1;CRt&!7{F7l@Rk*(S%Ka%(G|K5Gx(k3Scb=)!pRov z8)-?S`SDX&Kh`fPZRq&X$z#U7PF2ZmhS1f#Eq(CVl;jq}l7^3=mjtdaQo>R8H2R~b zW$>`!qlWO#Yq14?>kQVh4b@?$4jpxv#q-Z#qvmhhAr9j0v>eW%b63?N$tmN8HMK(w zM2ot)1RPyHEqUnh^l`~)=`{wA9Y1Cqv16g84)g4ESHFPQJByvY7uumQG_k`XSj-=m zW+A1Pz*0LbgXMNGV1b=3l2_X4c9`?yXR*BJEITc(Yj|o4dWT}JXnGJesA6Fw({)&D zr>myryvjLz#dE!#Cb*4!%TVm^c<&rWSOV;!`auZMpeJn&$^=_JfJlD(A{O8{zWEYX z%OGE9Dme@Jbgk5kCJ>-?;x&2sBdB(Cr9($KqB=lFnvl9jOQ-j0e5k-)}p5 zUdCwoKG`w*b6l=cH~bp*)a9sJ{T-{wr{2W|j{UdrLp7i#+{NdLnsg6GsFD2LFL*{J zd(Iyi;~|qhGp^O)eRPf&rKw8x%YUPvBkC_at}Ooi4^~lHAxuk9)JR=32T)0y_DI#) zeYIXnV`xb&QBh|@wIPZdQ&v0SQ9``VP8fdSNiQ10y?DxG7HK5h^5ni1H7`f~SF~Yj z0M>rbtIsUDj1{HOr+qBg@vxG%Sj|6~(b{!|n^;rpr>G-!wb~wXl2|dLfBA*fo`n`Z z{T5a?I)-}k?l#TW5#LB#q#U~(r@f}AQZ2RJ3iMPv?Sg_@nV^kSP{*&f`lJ<2YOOr@ z<<(f75A31Y9j&@+J(b{=-dd)b2P-9McNL)bP%X#EF0Pt*p`-w-3zqI z%3jrF+H6JbTcr(FSfw^-(-gIOn--)z%-N+SDXba8`_}r2Qu-%d%=|GtcE4tI^w^_4 zQ-VG6w0dgsS#nJKRZZLv1A=4uoeWl&Z$8X?9OqAIX(|ij&uY^xvR|t%?6^3Y`ZbwH zEMl>aXBV`oN@VI~?HA?XnEz;>s=5|mXlbhMgPYoI6^eCtwOCbm@q6v6s(be*q9pwC z_rKd;h7zI-k7%hyinq@4Z7kn>jCt}Uy=dj^|Ce^3x4*8{5N~Pu@HA%U>z`;pIUfF@ zc__5Ue`<%+;`dtDdnfynvwby@B2{_Hapv#%^SPF++#9H|>xyb>VY?Ldqs~sNeziv( zPA{S?-c9qeCz#FgxCAo+2Kcc(O3g2jeWa+bg4mCW`Y43ud&$LhZUr_`wV73A*A#WL zI=iK)W3}0Sr7^x9OIICwzX@xsxRI~254>ceRctq4ot=`yZsE&5$Exz(@K+sKApf!g zyX0UUSO*nDZO~`kPf$Xh;7OM;QiwU0c4pU9a7OlEixu$GzU+}z2L0QOQ}v1z^ol&A z9;?ms&(WgYESc3%u8bYY-co(P`ja>3Cz4#E>>Tr@xRuZAg}%H+DofU_DM@Lx^zeNv zu%hEaDtnAxwyLVGjpIx@yQK1c%>)XToYOuZkqsi@8uGs9DYAPevouY*wD{13POdaF zV*BcjA#btqDoi&rn7QLwGlLyfb$#Au_f+$zS;s`sjSghU4CS3JuoC>@9GZGo%xBY; zaH&P?fTAufVf&OTqehf&%}XyLSEgO0ozX|jS&9_lO;@r8;&(@U;z|}Lx|1JT$zmk& zU?r<7iHfUOGf5<`Vy{Uedlhwv5PrIfB}k$ZXPqUnjk6?4=&M&)HTzizs{i|ZQaV#dl z7(3I-z1A@K!zTVvaDSNX<{98g zTNt%sZ2NG7WQB=Ibvj?E zV`(`b{_#n(MSZstXy9PQz5IpXOchf1Q zsgp!$=!WP!*Qv(`&cgt{E6a57U>3p7SmI(o&thS+uS&loTwks@w{MmfCoeSu#F^_b zos>m!x0B74_~viJ_*D{@Ko0~^!8*k$|4pFr_gya@zug3@;5?nZ*c0uyIaT=P?JQh^ z9VJ5Z+V0{E*nxgLbcY#&MVTMpx=(J2($p;kAH6Ge_`n@3R%Ts6gYK*UATd$m-9-J~ zD};~W4|bTXz<0^;pnZj$K;HgcbAZ*Id%-9^9O(yK;^*?P1TQGei;Dtn_CXgr;V^pe z+lPu7e!a(BKKMQPC`uDIKVuF%^^KHoY<$TP%7#Td&7NJqlT4%@D-`kNcXyhZ=XM-* zL$uI3E|ULpVjzEgS7GAsBB1z7lEWWtohxk7Q|ED zV<9pf7raM^=N}hgO?yI)et+D|?l0PI`Q-{>iQ?Y;tIvukRew&4MTb3R>-y~>P}F$y zy)23kv}jhodymP4M)SW9MI1=FJEt?^98;@$n=tjm+OiPzx$5*5!Syg7p8&@9X!d z>mcz%Jl9`V=7?%i)QG*~$qS;jP+sG#>D2K3gw!h5#a>@iv%99}%YwbVj+4Ed0MaP{ z(w^(k_hP(m(7NVeQAVdwi%UEra$=_k)B&QnPdx{lNpXHFmqkeAADSEv?m^SODDGJX zuPM=lmRf+T6(ip#H}|wvtbf{R;V#w7iO;O6&Ia0~ltwpDp%G>%k(D@!SJL~+k#A6hX*G;Vdb@i$0ZcHxvf z0{SD_#pyUy(_b2HuJbI=rH1P-D|6jQ<-;$dsWo)MRb8_Bx8V4v7K< z{pKrqIzE@+*Y}!XUpntAkA~!=DDIm?|E0Y1K^8Cbp!UVm4}vHML~$RHYgh7p2U&9| zwRS^Z?P!t^#eMX^dY*ceRpU($nQL~RL)3!It&IQ1?WN{N zfBXdV#7y)~mwDtWpOP&<$#hY2O}jH;b{mSzawBc_3}M~IdEv0~B1K#7-9t84h( z+3P6!qPTBTk}nCh8uZ(7ogceQ>2mhC=#lmNDTB`RW!oJ0?9FEFz&qJTKFzE;qq3Rs9->IUq}p2UACpry`nPqDmz z(2A^cKMJj74-~8JF>{gYaExk4{wizb%>><8sPS>X%Fat&DNRIa?;1|Dr@Z}Gimy7( zqNS%X#|dM@Kccc4|M___>9ABtv_Zb?JV~t8STO(jxEcLtf>qf=v08q}f+b|)hgAES zr>gzZ#=?1=m2OhR0wMF*b;5As36J|8F?;D%8kPt*^;TDb4C6#=qNOCaYBr7ki9yuPDN_Xwzz8&J- ziCo!QGH^FrL4nT;tXqPVXl-MTBa{=J!%@99B(;Yvo-=(rt?D=%+9zZ tSSRT{olx*vO6fhZz})Q1tFV*{6tRiR6#vL_x2ds&;~yLz>+ zcXB)CW(BYSc(Of?YBMQ zO^mU^TUf=4Rk50m)ve%$u{zce-{W+Qw}M4{uW1FVcqUlEhOwU1SWCy+R`A6{9qV|K z59;bz&kBKDbr`<*|v5FL^=)Hq|l73igWFOvmO{h{9MQ z^|FpFtndQ9qT{PNwzNVOvI`Qhl^3?gHdeB=ttZ4_JMp!>pgIVuqmG>fSF*6GvyNS? zkSG*&)v=ou>S1>sd+7L@jys$21)W=r~Zv zK~{KG*q81Jt#Gg>4#A-o9A?GgI6}vfR%nl-bj;9kv=usG6$@sH=NR#kB|gSlFxwM4 z;y4SA*KvX%Ct9H=PO{)+9j92KFWRT-__`HRahi@~OMjfM;|v{VT45l*;RyrqO)I{I zvn=?w1s)1pXIpTN1?LL#9nmz;g7Yo7z=8`cxX6NwEx5#jh6R@jj%5~HZb5Fr6&8Hg zf-5bUW5HFzwAB_|qvKj@08AHSnk#(2PRI2+ZpgdaegNV|qix3md@s+VQ!?VFyw{Rn z)O2dyOyiQbtjm5)-=gDI9k&_XyBA}M(Y?nb%*acAEeLT&UV6_fh`B~m@2Y;YVU7(J z!%`i$*ua3Ld~r6$@SAq#<=G}9d$ed~rWL|zcp0eR-JR`dKF+vPayN}U4Hx=EC1^q9U`veZ?c-DsJ@KXe=t>bwc7U2cs z)}T0^w4Yf#5{2MrvcG=chVVcyE%XHhx2*JmjcoWiUKAf+*zildMDmF?ybQTS)D>eC zK`AHHb`x?1#1*QoWB3hdL}p&)4>WTB+NR7;y5%cU7ten@#VqpcHRatfA6~SRc^H2V zc+qb$UbmqRpHU3i@N4ukk_LuUB}7E9z; zfrpK$1NXWSZ-7yEP?iVfqR;WBQ8Z{OyG3D>+a@k=N_w8VkyU>fe|e+Untyv38}fSh zu$IxRMy0&*BRV2~;aiL}Hmoey2cqFkcnbg!G@wu=ss_<>;T`&%N8b|YN$DNjWA_5? zB0_`t^ywihTf+jPZHfUF!Xo;HBB1GWp0R6GxLxr20He=#l%CsDdhQ@)LI?-IYRU*o zC>N?|iU?_HtuMdRf+bYv1KUk?O1o7`CxZ^1%UED>TCj{TG=X8X&4{TdY)}&2AQ-xr zkq9v*mJ^2?Y2#E@C|P4;M%6NsJxQ|nzev8TB$tdXE0{upssAFl(p1^kMKX;f2mXs> z4y+>Q&NDt7-Bh|dfVu%Nn1*BsRDq#1mcu1NEY(*5cUTQ;S?EbIAjUOBj7|Xr8sjp9+LXFFgI3_tQg@VMb7~B6 zY78+omMTKn3fqJN$RjY}-!|Me0`cmOERs`MzR zB02Jcx&WU^zemI8M2YDX4HtQAP=}p>PwW1B^zDkiR71w*#e&)M*s z84TI*yBQ4Ga^QuZv*8c&xI4jifIs0c)6W*b$1q%nM=pN(FFZE=GK;+8PSUZ;AAL=K zI3Oj!Ug8Y5FgNO{TQ2Bso579kAa>OoH8|fuIE9d~SS)hlvt**hIt`9B4GsriX`D(J zB>xzyk#Wsj)9~LkTpHNLxV5K#h*=q=>`PVlIiO!Y1V6nU`JSfI57LllbA7S&T$$Jq zJ3Z3}Lr8}(JY4DMFLl(2vpXOyV1NvW0Ue*#^%G6m2W2`P?(B59oCB2f$SorBHR43n zkWoL%>ZiS=sedhvfEa@~rGKE(@36xlr~3H4klu*KAs+_63+{2d!ra78P>n)}6#j*# z$gdDd9dqeQ%w+4GV@(K7|;^Bh3i^8hml@E`Ep{sGT!Zb;Gld4Qw;8PM_%fF*d8o1g7* z<}-M9>ZRO9pzU7(eV+$7<{3aIp5MRV`AIxE|H_O>);|LV{R^PKGh|wrW9%OrFjj_4 zY(Vx?p(FPK7z*(g37SSbUsOpd||1XNK1sRg72 zh_20?Gr}JOX(>_L?|9IPX$mk}Iw}0+vMGpS3U_CnNtBr$c5!~eAZKUmo1L}928^Sr zJN~KZfzhC2r83LE;oA5le7_jSD3MMR1XuH4;6h#D6x!tHq17g|#Anb*e_7XssS^RgG^2sg6x@{X=L|$Wf~zm#)XGsZ z5aO;@?JvsWmd9{H6RT4fN|pk*d~Co}+AY}ScHwo}E|8LGa<}kwO2mc`hKIFyl+4s_Fl%s-j9FM)Zs@`*gVkIbcS>%zSvG5N39W zI|=S?JKn_N&Bb4p*#T4{2Z1<*;LGH~77&TA(9P+qbSc^js$pxWfo-G#V%9~1Cq`nF zbXdvpmq9Ge0?})+=J*18Oi+)zLNrYb*E55LFA#@@mEmpSaKh_J7bml5KedtO@O$*! zOIyr+;OTP7-s#43GbGHp+`^y+MV$TWbM`Qj0FKBaGZYf9{9qlZQn=Rkw$e zPlCwQntqo0?%2p9U~MCviiOqptgwyh$z$>_kUmqW%%HN03axXvkjnQ|eo=ga_kSr; z_V3tySlY;HWIPIIn{lqO@KI>sW*n_*!>o-w-0FL7#(qZOquV%@K3_0S{{pHv3&%r#F4NSN5KxvfDbSW_F*>c$8m5F z$HNhv0w-}QT*24jK1mm&9RqP51@U~Wf(tMf7h)}3gpF_szKTn+BQC=fT#o&bleQe3 zhVSBZT!XW5EgG0hpX+cvzK2_J6CT9Pc;1d%@EiJikFIBb#~t_=zK@S_Hx}a_O~X9R z9UYn#Kh(T&zvhR>wIDp9h2lvq9Iw(o8_c&LcM=u2nLDKt?+upA}) zl@LrT&uOaLM{gQrD|Uo<45MWz5be`RIGmWhEARU`2xQr?77<13ZAv z%hxEZ?-9%uID?glveC&WpF;RF9mtAd1BLNvdTX&2x+*?A2+b59o+ovcNy3MQz9tKa^ZPxFLG^dWVWc8IbO3~i5z@*~O(+_YGXA<7+ettvUaD(xV=v=^`%N$B9K zMPhZLED%6ZJK{+fFPk_iHp53?^)*gEN!Kh^BcZqker@zAZi=^!mBr2Rj&ZFx+4~2w z_8vLsK9s|smNmp4p1;s5nP16Czb#vV4donqf8ETxwaDyRJ{+rJd!!wF%_ZmhiWf`gX3tGerC|Hz|#8WrWmGPoTAMO>(eEH4| zSlw}}KQ>WPQ3J7@l4>*@w<&Y(W@24WiC%Fs`l!}~8Tf;0jhKy@s&3&z?5?_UcL|=C z*~PJ+qo1PA=HOh#*J}eFP})K^;bBEx+JY? z^fqcLyl#PM7O-1jx|K5HOda0fSPm=jI>&Lcr`PzjtYK*bMyB(^yBN!_A4gjiue7Wo z<3^=tWVabK7Qs4p;ONZs7DLm9WgvK$esP4IK!5boh7Ce+A2@W_$U!`<7+dhMC$X+| zs19%H&`F24`0kU~C~}q!lAxK5a>Z-}z1pDk%gvZO|B+h;8~p?q35#%PoS%HoAm2Y_y}9XM<(1+(vuD72I(OqdeZS!Mm{1X#RaX zx1L6Cj~pB2e}h*zjW2kt7Pnt(dF=t1z%xCtrg5T9d1KL4i{r#;EOra15aRwJRNoJw z8oWlQMO&E8zdT2;c_#4XpJEMrTWCU4|1{lWwu7cL;Q`-T03{HjIzlH( zAl+#Tl?-uWDa8c3f)Klzu9R$Qf|t0*bJwAp4&8OiZzS~>RQww%ApRGc{|z=E)t^)MYv}7fc z=Ams;imjg7Z*EdJ+1}UhR z3ff1Cx)-f&Q=ls0mR@B){t*i26*Tf;;1yXhh^y2+}Sv8)Ut=SxD6SNoP zi+{)4GqvB8S@v0)>D^&-wLJ=^;v#L9qBbwn1}X!+S83A}wP3v#tc=;TRZCMS*7vm} zHNfrnY4xo#tIf`*+XhM02PvO**cb`Lg~gZMxF7|E!j;N!hO9 z-^|LPvCQG4hqGGp?W-gIytdt4j&$Q)Hyo2GUryHeg{E3HF5h+5Kg9g`1UI&vCsffY z%R0ySFSSDX`v^zF%UYIFvh%ujQ<<>%wpL34_S?2&(%WR}+iv`5B1_;$e$?C@>^p6R zVq9}yyQHXzKWkaa3qSs$9Z=M^C)!pOHa(DC)ue?jGv8_5mn`h7iC9cF&#RYLewO_x0y^?s!(u(JX*1Qmvl{u^$vw zSdJB_C2U$Wo2YvCR~2?y_36qBmlw?;7tV3#{sAn(;SJY>z@1QICyPow(JQ zHCC;W&Dn&_M^{2G7MX_8C(*jx+W{VP_Judf{meb|R84t^NO zCMxLk;p}xKa$#lHhh6AhMHdgJNC1z`WZC?{pIXfFA)19JrfI2;gfaBym$_9N<~WnZ z&Z`K^8P7gePWfW^4&c*{liwbmVQxI-V{+cENi0jXE;ulu6F+>`Y;_Er$|kD5em#wu z0hcp_nG1B^H`!e^ur24XBE=UrkL^>`g#~Q40v$O#qBXBLk2U1e&oNKO*~R8)@}#A# zf%vr#pS+YMi3Gm=b8uVmp`l{XCknf2n5+o2Z3oWEsiRr#*v-g=rCqSO%^R`YM;jPkQdpeBDQhXqE7 zU06`WJXlF@6hx_A!bZ=HGrZ>$XFOk>!vZ8{>5)tbL%3E^^7D@7n>*NP;!d2;iRSW={P6Z^D%pCk8Q%fe|}TUm1Y z;DvdYC`v^UuSiP%HqPkcCpatfp{rShWc_=8@{_wX$3%%O;iKoq8I#H>*7rlu!i!d$ z9lEiaI<%#NYKmIJLgWB6Ttl^QMyuM%YgnknK2bIJm##DtqPRNrx2lS@aSQb1H`bVL z?RFHpRiv$fD6VehiGsh0)Rjy<)v%GMsK{xr?cw{>kn>!@(WWc+&t*~k`dStwt#SL~ z_s(-Ep@~x2rKi)n3)V!*^(YkYd`)f>rK$^8+n$1}0-v7CLZu-&xuj-PKUr(+y5u2# zXJX}{ zUFY8GO-H3RyYb>}N?fA6=mLFbObNS{XRS8b>$b{VP(b|=g?{4Z{M$IA!W5;r|5Wti zmkD0l^y7L`TyrKLvw_7LnO(hj(gqW$aj%!AM9}Dn($I+`q9uHeU~eVm3pSAaf<>Yt zj(@z6pnW%*eX6*Tn(i1%YovieJYyfT$!UJ+N%R7qv6+QvAFkk?x3HSLcm?YG%0|Zqt5nmG)f6~i?ljG+^yipS&v$jtjf#KDM&e()fqq04zNy5$?-5?`X4USsiA6}; zV>eOlms?eBqwQq-^i8IgBMrK*_z!K4L}}*I`G}p0|K=tZCC7fx$(vmYh)on%k7w*r ztQ|L-Q8a8bDYWOS+C%%$o40DBAxW=@6xfi%E?S39+`a zPiwXi&g(}-MJ)ez3k#Mux}3mVWc`n;ATkeR9=zjL)1s8Egw(c3HUHSj$`_s|mtH$) zhWvw1zD-D^a2MrO7syFps3Bi;1w(n%Hq)c~u1#4_`*je-)lEK^m5zsfy!h5bEI>xc ziaV6Ka63iF&>ITw);80NkGGLw!@p6rFK;(%Q?^s>$h!*4+TDxq+-_>F7tp)fL|PF< zsq13tl?MuhHtst2+ffo>oljP|N=_D~kqiHZ|CHg++F@#*zk@V?@u#yXgg-1aom6^4 zc)HWKo;dj}yyg2WSdL!m`vm31IObD^XsKzwd}2w8* zvF5;$X=BGel_guXiMZQiBXwUCS7F^Mg^k=GPd<+3m^5SVPBNpI?oWgnbSP0d@Sdpc z9i(b&f56H~-gX~QZ9$kq>G*9p-|>Noa#XZbs;Kx=Dro+tok<>c?om(bh$yZ}?Yl~f zf7C8>lFr*jD9d70ZBb<{gx5M{diUb5t9DMJ9*NS@#UM*kbOQje46w;^;gyiha*P>~5vTBOi%PPq+ zX}gzdfA6NC>|c5DReR0e?-ngfdnx{+o|+%GP)?RP;!st%xQKQJqPR}b&@{!rXbAmC zGqu0wArraO^!h%+dotMB?#0jVGd(%XcDLX&8W~Ysr`>xa1^>%Z>xy4Onms0sqPS+Y zGh-yGk(=zpbMj65cjc45$cZH_9{g`=kw7iKoqc5s%~(-f_d##c-3m;(S=Iai!8sc}Z z<>fH--A`_NXM?krHhJr*cTOnZNB55fk|#uQRlQ-G61urndv-~hIjm3OkCe|vakW6- zsl-McVCCiT^g0!D@h1K1L=@K@Qk#6mT6BO_l*ayifQ+44sA}m59>8~OFxRBs1=KYD zglbw}VD|2asI7Ba)n=ZeAQf3tVnrRKru=iNY3M-~CXI2P*Tqn|B#zNVf>mv8?g`nn zFGWR7PUrOsQg)5cH}6&;IZ<5aZv88YHS-Fc45wYDY4X7#(~QH12x|M+s-1r3?9Lxv zr*`N5asJ|C2d>jR5yf@xE%-(WWgKRqa$yvQfBy4fS{RRhr<(q6o4I=2KTKM3epIzz z-Pb&Mvm>SfosLk`xL;(GakHO=4=tId_o{9^-<2Xrl=d#Z_~Fk|_63h9hgK+L{?e

6s~iLbvIZ&_zjdLF%gU=#PkX5i+$nN|a)OQp;U6(UpVsnazFw zqr`DtR~+Sa7R}EbHG^MVNAw{@qPRxvCU3=0*A(V~Y`;7VRE69p6Yd+%>2EoYI;zex$~w~*|TS%qk`>1ykhe` zVJ_RTC#W{Bj;M|2*(Xe=%onvo>vR8;ERkP3VeS*7b6>r7i(*g|*CG76iC|Ut0BI*l zHsWPbQIqdD$tp-A&x+bh?Nn{KQ!GZ-CY_?%mYr4Y+*7Qa^w+th@iQ7z=S6Xi_tYNz z=qc7x%34p8?1Mf^mhNhNN*Akd*G$zbQ^bnmI)m@h`AXPTn9g)wa}e|3AD=cy`-;FD zK!+^R9yN;EYn(BcgVMX6r)Tx;OvRrvhW=|p%o;fhcN~A`N1jU&rp=om+T)DLw0nI_ zaME)Bk4aOn$+Cs_{@6@A;<6{5;z$(NU0BHLinae#X5*iHY@U+(RDH0R_bVVJ=k3mR zH(tTcJbA58%uXeJLaOG?R7UuuTlk_+%sw3m+jM3*4WuZp>N>oo;KVHsb@_kqePQ+KJR>vt{eBCHS^5{QG0Bms`Xt+{t?F+Il$rys^paB Ss(btr!Qa}W<}zAq;Qs;s2)?BN diff --git a/lib/treetable.jar b/lib/treetable.jar new file mode 100644 index 0000000000000000000000000000000000000000..610bf18d4ec4fb1abc7d9cdb2a5634e1c3fe89b7 GIT binary patch literal 26340 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 literal 0 HcmV?d00001 diff --git a/libsrc/cmykjpeg/nbproject/build-impl.xml b/libsrc/cmykjpeg/nbproject/build-impl.xml index 4044e3e5a..ed218bcac 100644 --- a/libsrc/cmykjpeg/nbproject/build-impl.xml +++ b/libsrc/cmykjpeg/nbproject/build-impl.xml @@ -191,7 +191,12 @@ is divided into following sections: - + + + + + + @@ -217,6 +222,7 @@ is divided into following sections: + @@ -693,7 +699,7 @@ is divided into following sections: - + @@ -768,7 +774,7 @@ is divided into following sections: - + @@ -795,7 +801,7 @@ is divided into following sections: - + diff --git a/libsrc/cmykjpeg/nbproject/genfiles.properties b/libsrc/cmykjpeg/nbproject/genfiles.properties index 605d6401d..1b65a7437 100644 --- a/libsrc/cmykjpeg/nbproject/genfiles.properties +++ b/libsrc/cmykjpeg/nbproject/genfiles.properties @@ -4,5 +4,5 @@ build.xml.stylesheet.CRC32=8064a381@1.75.2.48 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=73f9688e -nbproject/build-impl.xml.script.CRC32=de1179e8 -nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.75.2.48 +nbproject/build-impl.xml.script.CRC32=ce0b030d +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 diff --git a/libsrc/jpproxy/nbproject/build-impl.xml b/libsrc/jpproxy/nbproject/build-impl.xml index fa9ad0fbe..ec2302d65 100644 --- a/libsrc/jpproxy/nbproject/build-impl.xml +++ b/libsrc/jpproxy/nbproject/build-impl.xml @@ -189,7 +189,12 @@ is divided into following sections: - + + + + + + @@ -215,6 +220,7 @@ is divided into following sections: + @@ -680,7 +686,7 @@ is divided into following sections: - + @@ -755,7 +761,7 @@ is divided into following sections: - + @@ -782,7 +788,7 @@ is divided into following sections: - + diff --git a/libsrc/jpproxy/nbproject/genfiles.properties b/libsrc/jpproxy/nbproject/genfiles.properties index 9e4b5fd3d..c37be34a0 100644 --- a/libsrc/jpproxy/nbproject/genfiles.properties +++ b/libsrc/jpproxy/nbproject/genfiles.properties @@ -4,5 +4,5 @@ nbbuild.xml.stylesheet.CRC32=8064a381@1.74.2.48 # This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. # Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. nbproject/build-impl.xml.data.CRC32=0a5363c8 -nbproject/build-impl.xml.script.CRC32=13f57099 -nbproject/build-impl.xml.stylesheet.CRC32=876e7a8f@1.74.2.48 +nbproject/build-impl.xml.script.CRC32=6f75ce45 +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 diff --git a/libsrc/treetable/build.xml b/libsrc/treetable/build.xml new file mode 100644 index 000000000..8a974bcd8 --- /dev/null +++ b/libsrc/treetable/build.xml @@ -0,0 +1,73 @@ + + + + + + + + + + + Builds, tests, and runs the project treetable. + + + diff --git a/libsrc/treetable/manifest.mf b/libsrc/treetable/manifest.mf new file mode 100644 index 000000000..328e8e5bc --- /dev/null +++ b/libsrc/treetable/manifest.mf @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +X-COMMENT: Main-Class will be added automatically by build + diff --git a/libsrc/treetable/nbproject/build-impl.xml b/libsrc/treetable/nbproject/build-impl.xml new file mode 100644 index 000000000..a53c99b03 --- /dev/null +++ b/libsrc/treetable/nbproject/build-impl.xml @@ -0,0 +1,1419 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set src.dir + Must set test.src.dir + Must set build.dir + Must set dist.dir + Must set build.classes.dir + Must set dist.javadoc.dir + Must set build.test.classes.dir + Must set build.test.results.dir + Must set build.classes.excludes + Must set dist.jar + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + No tests executed. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must set JVM to use for profiling in profiler.info.jvm + Must set profiler agent JVM arguments in profiler.info.jvmargs.agent + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + To run this application from the command line without Ant, try: + + java -jar "${dist.jar.resolved}" + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + Must select one file in the IDE or set run.class + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set debug.class + + + + + Must select one file in the IDE or set debug.class + + + + + Must set fix.includes + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + Must select one file in the IDE or set profile.class + This target only works when run from inside the NetBeans IDE. + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + This target only works when run from inside the NetBeans IDE. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select one file in the IDE or set run.class + + + + + + Must select some files in the IDE or set test.includes + + + + + Must select one file in the IDE or set run.class + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Must select some files in the IDE or set javac.includes + + + + + + + + + + + + + + + + + + + + Some tests failed; see details above. + + + + + + + + + Must select some files in the IDE or set test.includes + + + + Some tests failed; see details above. + + + + Must select some files in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + Some tests failed; see details above. + + + + + Must select one file in the IDE or set test.class + + + + Must select one file in the IDE or set test.class + Must select some method in the IDE or set test.method + + + + + + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + Must select one file in the IDE or set applet.url + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libsrc/treetable/nbproject/genfiles.properties b/libsrc/treetable/nbproject/genfiles.properties new file mode 100644 index 000000000..d931ac2ee --- /dev/null +++ b/libsrc/treetable/nbproject/genfiles.properties @@ -0,0 +1,8 @@ +build.xml.data.CRC32=3ded4556 +build.xml.script.CRC32=4673fb60 +build.xml.stylesheet.CRC32=8064a381@1.75.2.48 +# This file is used by a NetBeans-based IDE to track changes in generated files such as build-impl.xml. +# Do not edit this file. You may delete it but then the IDE will never regenerate such files for you. +nbproject/build-impl.xml.data.CRC32=3ded4556 +nbproject/build-impl.xml.script.CRC32=646636b1 +nbproject/build-impl.xml.stylesheet.CRC32=05530350@1.79.1.48 diff --git a/libsrc/treetable/nbproject/project.properties b/libsrc/treetable/nbproject/project.properties new file mode 100644 index 000000000..93930aa33 --- /dev/null +++ b/libsrc/treetable/nbproject/project.properties @@ -0,0 +1,73 @@ +annotation.processing.enabled=true +annotation.processing.enabled.in.editor=false +annotation.processing.processor.options= +annotation.processing.processors.list= +annotation.processing.run.all.processors=true +annotation.processing.source.output=${build.generated.sources.dir}/ap-source-output +build.classes.dir=${build.dir}/classes +build.classes.excludes=**/*.java,**/*.form +# This directory is removed when the project is cleaned: +build.dir=build +build.generated.dir=${build.dir}/generated +build.generated.sources.dir=${build.dir}/generated-sources +# Only compile against the classpath explicitly listed here: +build.sysclasspath=ignore +build.test.classes.dir=${build.dir}/test/classes +build.test.results.dir=${build.dir}/test/results +# Uncomment to specify the preferred debugger connection transport: +#debug.transport=dt_socket +debug.classpath=\ + ${run.classpath} +debug.test.classpath=\ + ${run.test.classpath} +# Files in build.classes.dir which should be excluded from distribution jar +dist.archive.excludes= +# This directory is removed when the project is cleaned: +dist.dir=dist +dist.jar=${dist.dir}/treetable.jar +dist.javadoc.dir=${dist.dir}/javadoc +excludes= +includes=** +jar.compress=false +javac.classpath= +# Space-separated list of extra javac options +javac.compilerargs= +javac.deprecation=false +javac.processorpath=\ + ${javac.classpath} +javac.source=1.8 +javac.target=1.8 +javac.test.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +javac.test.processorpath=\ + ${javac.test.classpath} +javadoc.additionalparam= +javadoc.author=false +javadoc.encoding=${source.encoding} +javadoc.noindex=false +javadoc.nonavbar=false +javadoc.notree=false +javadoc.private=false +javadoc.splitindex=true +javadoc.use=true +javadoc.version=false +javadoc.windowtitle= +main.class=de.hameister.treetable.TreeTableMain +manifest.file=manifest.mf +meta.inf.dir=${src.dir}/META-INF +mkdist.disabled=false +platform.active=default_platform +run.classpath=\ + ${javac.classpath}:\ + ${build.classes.dir} +# Space-separated list of JVM arguments used when running the project. +# You may also define separate properties like run-sys-prop.name=value instead of -Dname=value. +# To set system properties for unit tests define test-sys-prop.name=value: +run.jvmargs= +run.test.classpath=\ + ${javac.test.classpath}:\ + ${build.test.classes.dir} +source.encoding=UTF-8 +src.dir=src +test.src.dir=test diff --git a/libsrc/treetable/nbproject/project.xml b/libsrc/treetable/nbproject/project.xml new file mode 100644 index 000000000..69f12b7e3 --- /dev/null +++ b/libsrc/treetable/nbproject/project.xml @@ -0,0 +1,15 @@ + + + org.netbeans.modules.java.j2seproject + + + treetable + + + + + + + + + diff --git a/libsrc/treetable/src/de/hameister/treetable/MyAbstractTreeTableModel.java b/libsrc/treetable/src/de/hameister/treetable/MyAbstractTreeTableModel.java new file mode 100644 index 000000000..ba1c398d1 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyAbstractTreeTableModel.java @@ -0,0 +1,91 @@ +package de.hameister.treetable; + +import javax.swing.event.EventListenerList; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.tree.TreePath; + +public abstract class MyAbstractTreeTableModel implements MyTreeTableModel { + + protected Object root; + protected EventListenerList listenerList = new EventListenerList(); + + private static final int CHANGED = 0; + private static final int INSERTED = 1; + private static final int REMOVED = 2; + private static final int STRUCTURE_CHANGED = 3; + + public MyAbstractTreeTableModel(Object root) { + this.root = root; + } + + public Object getRoot() { + return root; + } + + public boolean isLeaf(Object node) { + return getChildCount(node) == 0; + } + + public void valueForPathChanged(TreePath path, Object newValue) { + } + + /** + * Die Methode wird normalerweise nicht aufgerufen. + */ + public int getIndexOfChild(Object parent, Object child) { + return 0; + } + + public void addTreeModelListener(TreeModelListener l) { + listenerList.add(TreeModelListener.class, l); + } + + public void removeTreeModelListener(TreeModelListener l) { + listenerList.remove(TreeModelListener.class, l); + } + + private void fireTreeNode(int changeType, Object source, Object[] path, int[] childIndices, Object[] children) { + Object[] listeners = listenerList.getListenerList(); + TreeModelEvent e = new TreeModelEvent(source, path, childIndices, children); + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + + switch (changeType) { + case CHANGED: + ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e); + break; + case INSERTED: + ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e); + break; + case REMOVED: + ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e); + break; + case STRUCTURE_CHANGED: + ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e); + break; + default: + break; + } + + } + } + } + + protected void fireTreeNodesChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + fireTreeNode(CHANGED, source, path, childIndices, children); + } + + protected void fireTreeNodesInserted(Object source, Object[] path, int[] childIndices, Object[] children) { + fireTreeNode(INSERTED, source, path, childIndices, children); + } + + protected void fireTreeNodesRemoved(Object source, Object[] path, int[] childIndices, Object[] children) { + fireTreeNode(REMOVED, source, path, childIndices, children); + } + + protected void fireTreeStructureChanged(Object source, Object[] path, int[] childIndices, Object[] children) { + fireTreeNode(STRUCTURE_CHANGED, source, path, childIndices, children); + } + +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyDataModel.java b/libsrc/treetable/src/de/hameister/treetable/MyDataModel.java new file mode 100644 index 000000000..49ba6079b --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyDataModel.java @@ -0,0 +1,64 @@ +package de.hameister.treetable; + + + +import java.util.Date; + +public class MyDataModel extends MyAbstractTreeTableModel { + + // Spalten Name. + + static protected String[] columnNames = {"Knotentext", "String", "Datum", "Integer"}; + + // Spalten Typen. + static protected Class[] columnTypes = {MyTreeTableModel.class, String.class, Date.class, Integer.class}; + + public MyDataModel(MyDataNode rootNode) { + super(rootNode); + root = rootNode; + } + + public Object getChild(Object parent, int index) { + return ((MyDataNode) parent).getChildren().get(index); + } + + public int getChildCount(Object parent) { + return ((MyDataNode) parent).getChildren().size(); + } + + public int getColumnCount() { + return columnNames.length; + } + + public String getColumnName(int column) { + return columnNames[column]; + } + + public Class getColumnClass(int column) { + return columnTypes[column]; + } + + public Object getValueAt(Object node, int column) { + switch (column) { + case 0: + return ((MyDataNode) node).getName(); + case 1: + return ((MyDataNode) node).getCapital(); + case 2: + return ((MyDataNode) node).getDeclared(); + case 3: + return ((MyDataNode) node).getArea(); + default: + break; + } + return null; + } + + public boolean isCellEditable(Object node, int column) { + return true; // Important to activate TreeExpandListener + } + + public void setValueAt(Object aValue, Object node, int column) { + } + +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyDataNode.java b/libsrc/treetable/src/de/hameister/treetable/MyDataNode.java new file mode 100644 index 000000000..6c6c43ff0 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyDataNode.java @@ -0,0 +1,56 @@ +package de.hameister.treetable; + + + +import java.util.Collections; +import java.util.Date; +import java.util.List; + +public class MyDataNode { + + private String name; + private String capital; + private Date declared; + private Integer area; + + private List children; + + public MyDataNode(String name, String capital, Date declared, Integer area, List children) { + this.name = name; + this.capital = capital; + this.declared = declared; + this.area = area; + this.children = children; + + if (this.children == null) { + this.children = Collections.emptyList(); + } + } + + public String getName() { + return name; + } + + public String getCapital() { + return capital; + } + + public Date getDeclared() { + return declared; + } + + public Integer getArea() { + return area; + } + + public List getChildren() { + return children; + } + + /** + * Knotentext vom JTree. + */ + public String toString() { + return name; + } +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java new file mode 100644 index 000000000..2da462026 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTable.java @@ -0,0 +1,51 @@ +package de.hameister.treetable; + +import java.awt.Dimension; + +import javax.swing.JTable; +import javax.swing.plaf.basic.BasicTableUI; + +public class MyTreeTable extends JTable { + + private MyTreeTableCellRenderer tree; + private MyTreeTableModel treeTableModel; + + public MyTreeTableCellRenderer getTree() { + return tree; + } + + public MyTreeTableModel getTreeTableModel() { + return treeTableModel; + } + + public void setTreeModel(MyTreeTableModel treeTableModel) { + // JTree erstellen. + this.treeTableModel = treeTableModel; + tree = new MyTreeTableCellRenderer(this, treeTableModel); + + // Modell setzen. + super.setModel(new MyTreeTableModelAdapter(treeTableModel, tree)); + + // Gleichzeitiges Selektieren fuer Tree und Table. + MyTreeTableSelectionModel selectionModel = new MyTreeTableSelectionModel(); + tree.setSelectionModel(selectionModel); //For the tree + setSelectionModel(selectionModel.getListSelectionModel()); //For the table + + // Renderer fuer den Tree. + setDefaultRenderer(MyTreeTableModel.class, tree); + // Editor fuer die TreeTable + setDefaultEditor(MyTreeTableModel.class, new MyTreeTableCellEditor(tree, this)); + + // Kein Grid anzeigen. + setShowGrid(false); + + // Keine Abstaende. + setIntercellSpacing(new Dimension(0, 0)); + } + + public MyTreeTable(MyTreeTableModel treeTableModel) { + super(); + setUI(new BasicTableUI()); + setTreeModel(treeTableModel); + } +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellEditor.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellEditor.java new file mode 100644 index 000000000..859862d89 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellEditor.java @@ -0,0 +1,44 @@ +package de.hameister.treetable; + + + +import java.awt.Component; +import java.awt.event.MouseEvent; +import java.util.EventObject; + +import javax.swing.AbstractCellEditor; +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.table.TableCellEditor; + +public class MyTreeTableCellEditor extends AbstractCellEditor implements TableCellEditor { + + private JTree tree; + private JTable table; + + public MyTreeTableCellEditor(JTree tree, JTable table) { + this.tree = tree; + this.table = table; + } + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int r, int c) { + return tree; + } + + public boolean isCellEditable(EventObject e) { + if (e instanceof MouseEvent) { + int colunm1 = 0; + MouseEvent me = (MouseEvent) e; + int doubleClick = 2; + MouseEvent newME = new MouseEvent(tree, me.getID(), me.getWhen(), me.getModifiers(), me.getX() - table.getCellRect(0, colunm1, true).x, me.getY(), doubleClick, me.isPopupTrigger()); + tree.dispatchEvent(newME); + } + return false; + } + + @Override + public Object getCellEditorValue() { + return null; + } + +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellRenderer.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellRenderer.java new file mode 100644 index 000000000..30fb20abe --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableCellRenderer.java @@ -0,0 +1,75 @@ +package de.hameister.treetable; + +import java.awt.Component; +import java.awt.Graphics; + +import javax.swing.JTable; +import javax.swing.JTree; +import javax.swing.plaf.basic.BasicTableUI; +import javax.swing.plaf.basic.BasicTreeUI; +import javax.swing.table.TableCellRenderer; +import javax.swing.tree.TreeModel; + +public class MyTreeTableCellRenderer extends JTree implements TableCellRenderer { + + /** + * Die letzte Zeile, die gerendert wurde. + */ + protected int visibleRow; + + private MyTreeTable treeTable; + + public MyTreeTableCellRenderer(MyTreeTable treeTable, TreeModel model) { + super(model); + setUI(new BasicTreeUI()); + + this.treeTable = treeTable; + + // Setzen der Zeilenhoehe fuer die JTable + // Muss explizit aufgerufen werden, weil treeTable noch + // null ist, wenn super(model) setRowHeight aufruft! + setRowHeight(getRowHeight()); + } + + /** + * Tree und Table muessen die gleiche Hoehe haben. + */ + public void setRowHeight(int rowHeight) { + if (rowHeight > 0) { + super.setRowHeight(rowHeight); + if (treeTable != null && treeTable.getRowHeight() != rowHeight) { + treeTable.setRowHeight(getRowHeight()); + } + } + } + + /** + * Tree muss die gleiche Hoehe haben wie Table. + */ + public void setBounds(int x, int y, int w, int h) { + super.setBounds(x, 0, w, treeTable.getHeight()); + } + + /** + * Sorgt fuer die Einrueckung der Ordner. + */ + public void paint(Graphics g) { + g.translate(0, -visibleRow * getRowHeight()); + + super.paint(g); + } + + /** + * Liefert den Renderer mit der passenden Hintergrundfarbe zurueck. + */ + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (isSelected) { + setBackground(table.getSelectionBackground()); + } else { + setBackground(table.getBackground()); + } + + visibleRow = row; + return this; + } +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModel.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModel.java new file mode 100644 index 000000000..0d24776bc --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModel.java @@ -0,0 +1,58 @@ +package de.hameister.treetable; + + + +import javax.swing.tree.TreeModel; + +public interface MyTreeTableModel extends TreeModel { + + /** + * Returns the number of available columns. + * + * @return Number of Columns + */ + public int getColumnCount(); + + /** + * Returns the column name. + * + * @param column Column number + * @return Column name + */ + public String getColumnName(int column); + + /** + * Returns the type (class) of a column. + * + * @param column Column number + * @return Class + */ + public Class getColumnClass(int column); + + /** + * Returns the value of a node in a column. + * + * @param node Node + * @param column Column number + * @return Value of the node in the column + */ + public Object getValueAt(Object node, int column); + + /** + * Check if a cell of a node in one column is editable. + * + * @param node Node + * @param column Column number + * @return true/false + */ + public boolean isCellEditable(Object node, int column); + + /** + * Sets a value for a node in one column. + * + * @param aValue New value + * @param node Node + * @param column Column number + */ + public void setValueAt(Object aValue, Object node, int column); +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModelAdapter.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModelAdapter.java new file mode 100644 index 000000000..90c906aff --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableModelAdapter.java @@ -0,0 +1,63 @@ +package de.hameister.treetable; + +import java.awt.Rectangle; + +import javax.swing.JTree; +import javax.swing.event.TreeExpansionEvent; +import javax.swing.event.TreeExpansionListener; +import javax.swing.table.AbstractTableModel; +import javax.swing.tree.TreePath; + +public class MyTreeTableModelAdapter extends AbstractTableModel { + + JTree tree; + MyTreeTableModel treeTableModel; + + public MyTreeTableModelAdapter(MyTreeTableModel treeTableModel, JTree tree) { + this.tree = tree; + this.treeTableModel = treeTableModel; + + tree.addTreeExpansionListener(new TreeExpansionListener() { + public void treeExpanded(TreeExpansionEvent event) { + fireTableDataChanged(); + } + + public void treeCollapsed(TreeExpansionEvent event) { + fireTableDataChanged(); + } + }); + } + + public int getColumnCount() { + return treeTableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return treeTableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return treeTableModel.getColumnClass(column); + } + + public int getRowCount() { + return tree.getRowCount(); + } + + protected Object nodeForRow(int row) { + TreePath treePath = tree.getPathForRow(row); + return treePath.getLastPathComponent(); + } + + public Object getValueAt(int row, int column) { + return treeTableModel.getValueAt(nodeForRow(row), column); + } + + public boolean isCellEditable(int row, int column) { + return treeTableModel.isCellEditable(nodeForRow(row), column); + } + + public void setValueAt(Object value, int row, int column) { + treeTableModel.setValueAt(value, nodeForRow(row), column); + } +} diff --git a/libsrc/treetable/src/de/hameister/treetable/MyTreeTableSelectionModel.java b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableSelectionModel.java new file mode 100644 index 000000000..c15bbe052 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/MyTreeTableSelectionModel.java @@ -0,0 +1,26 @@ +package de.hameister.treetable; + + + +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import javax.swing.tree.DefaultTreeSelectionModel; + +public class MyTreeTableSelectionModel extends DefaultTreeSelectionModel { + + public MyTreeTableSelectionModel() { + super(); + + getListSelectionModel().addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + + } + }); + } + + ListSelectionModel getListSelectionModel() { + return listSelectionModel; + } +} diff --git a/libsrc/treetable/src/de/hameister/treetable/TreeTableMain.java b/libsrc/treetable/src/de/hameister/treetable/TreeTableMain.java new file mode 100644 index 000000000..fa9947af2 --- /dev/null +++ b/libsrc/treetable/src/de/hameister/treetable/TreeTableMain.java @@ -0,0 +1,84 @@ +package de.hameister.treetable; + +import java.awt.Container; +import java.awt.GridLayout; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +import javax.swing.JFrame; +import javax.swing.JScrollPane; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +public class TreeTableMain extends JFrame { + + public TreeTableMain() { + super("Tree Table Demo"); + + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + setLayout(new GridLayout(0, 1)); + MyAbstractTreeTableModel treeTableModel = new MyDataModel(createDataStructure()); + + MyTreeTable myTreeTable = new MyTreeTable(treeTableModel); + + Container cPane = getContentPane(); + + cPane.add(new JScrollPane(myTreeTable)); + + setSize(1000, 800); + setLocationRelativeTo(null); + + } + + private static MyDataNode createDataStructure() { + List children1 = new ArrayList(); + children1.add(new MyDataNode("N12", "C12", new Date(), Integer.valueOf(50), null)); + children1.add(new MyDataNode("N13", "C13", new Date(), Integer.valueOf(60), null)); + children1.add(new MyDataNode("N14", "C14", new Date(), Integer.valueOf(70), null)); + children1.add(new MyDataNode("N15", "C15", new Date(), Integer.valueOf(80), null)); + + List children2 = new ArrayList(); + children2.add(new MyDataNode("N12", "C12", new Date(), Integer.valueOf(10), null)); + children2.add(new MyDataNode("N13", "C13", new Date(), Integer.valueOf(20), children1)); + children2.add(new MyDataNode("N14", "C14", new Date(), Integer.valueOf(30), null)); + children2.add(new MyDataNode("N15", "C15", new Date(), Integer.valueOf(40), null)); + + List rootNodes = new ArrayList(); + rootNodes.add(new MyDataNode("N1", "C1", new Date(), Integer.valueOf(10), children2)); + rootNodes.add(new MyDataNode("N2", "C2", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N3", "C3", new Date(), Integer.valueOf(10), children2)); + rootNodes.add(new MyDataNode("N4", "C4", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N5", "C5", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N6", "C6", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N7", "C7", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N8", "C8", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N9", "C9", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N10", "C10", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N11", "C11", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N12", "C7", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N13", "C8", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N14", "C9", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N15", "C10", new Date(), Integer.valueOf(10), children1)); + rootNodes.add(new MyDataNode("N16", "C11", new Date(), Integer.valueOf(10), children1)); + MyDataNode root = new MyDataNode("R1", "R1", new Date(), Integer.valueOf(10), rootNodes); + + return root; + } + + public static void main(final String[] args) { + Runnable gui = new Runnable() { + + public void run() { + try { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + } catch (Exception e) { + e.printStackTrace(); + } + new TreeTableMain().setVisible(true); + } + }; + SwingUtilities.invokeLater(gui); + } +} diff --git a/nbproject/project.xml b/nbproject/project.xml index 286b09cc5..cfa9340f0 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -308,7 +308,7 @@ src - lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar + lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/tablelayout.jar;lib/jsyntaxpane-0.9.5.jar;lib/JavactiveX.jar;lib/flashdebugger.jar;lib/treetable.jar build javadoc reports diff --git a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java index 5df50caed..f90e6cd2f 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebugPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/DebugPanel.java @@ -21,6 +21,11 @@ import com.jpexs.debugger.flash.messages.in.InBreakAtExt; import com.jpexs.debugger.flash.messages.in.InFrame; import com.jpexs.decompiler.flash.gui.DebuggerHandler.BreakListener; import com.jpexs.decompiler.flash.gui.abc.ABCPanel; +import de.hameister.treetable.MyAbstractTreeTableModel; +import de.hameister.treetable.MyTreeTable; +import de.hameister.treetable.MyTreeTableModel; +import de.hameister.treetable.MyTreeTableModelAdapter; +import de.hameister.treetable.MyTreeTableSelectionModel; import java.awt.BorderLayout; import java.awt.Color; import java.awt.FlowLayout; @@ -43,7 +48,15 @@ import javax.swing.JTable; import javax.swing.JTextArea; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.plaf.basic.BasicTableUI; +import javax.swing.plaf.basic.BasicTreeUI; import javax.swing.table.DefaultTableModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; /** * @@ -51,11 +64,11 @@ import javax.swing.table.DefaultTableModel; */ public class DebugPanel extends JPanel { - private JTable debugRegistersTable; + private MyTreeTable debugRegistersTable; - private JTable debugLocalsTable; + private MyTreeTable debugLocalsTable; //JTable debugLocalsTable; - private JTable debugScopeTable; + private MyTreeTable debugScopeTable; private JTable callStackTable; @@ -88,10 +101,34 @@ public class DebugPanel extends JPanel { private SelectedTab selectedTab = null; + private void safeSetTreeModel(MyTreeTable tt, MyTreeTableModel tmodel) { + List> expanded = View.getExpandedNodes(tt.getTree()); + + int selRows[] = tt.getSelectedRows(); + + TreePath selPaths[] = new TreePath[selRows.length]; + for (int i = 0; i < selRows.length; i++) { + selPaths[i] = tt.getTree().getPathForRow(selRows[i]); + } + tt.setTreeModel(tmodel); + //tt.getTree().setRootVisible(false); + + View.expandTreeNodes(tt.getTree(), expanded); + for (int i = 0; i < selRows.length; i++) { + selRows[i] = tt.getTree().getRowForPath(selPaths[i]); + if (i == 0) { + tt.setRowSelectionInterval(selRows[i], selRows[i]); + } else { + tt.addRowSelectionInterval(selRows[i], selRows[i]); + } + } + + } + public DebugPanel() { super(new BorderLayout()); - debugRegistersTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); - debugLocalsTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); + debugRegistersTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>())); + debugLocalsTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>())); //Add watch feature, commented out. I tried it, but without success. I can't add watch in Flash Pro or FDB either. :-( /* @@ -161,7 +198,7 @@ public class DebugPanel extends JPanel { debugScopeTable.addMouseListener(watchHandler); */ - debugScopeTable = new JTable(new ABCPanel.VariablesTableModel(new ArrayList<>(), new ArrayList<>())); + debugScopeTable = new MyTreeTable(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>())); callStackTable = new JTable(); stackTable = new JTable(); @@ -271,21 +308,56 @@ public class DebugPanel extends JPanel { for (int i = 0; i < f.registers.size(); i++) { regVarIds.add(0L); } - debugRegistersTable.setModel(new ABCPanel.VariablesTableModel(f.registers, regVarIds)); + safeSetTreeModel(debugRegistersTable, new ABCPanel.VariablesTableModel(debugRegistersTable, f.registers, regVarIds)); List locals = new ArrayList<>(); locals.addAll(f.arguments); locals.addAll(f.variables); List localIds = new ArrayList<>(); - localIds.addAll(f.argumentIds); - localIds.addAll(f.variableIds); + localIds.addAll(f.argumentFrameIds); + localIds.addAll(f.frameIds); - debugLocalsTable.setModel(new ABCPanel.VariablesTableModel(locals, localIds)); - debugScopeTable.setModel(new ABCPanel.VariablesTableModel(f.scopeChain, f.scopeChainIds)); + safeSetTreeModel(debugLocalsTable, new ABCPanel.VariablesTableModel(debugLocalsTable, locals, localIds)); + safeSetTreeModel(debugScopeTable, new ABCPanel.VariablesTableModel(debugScopeTable, f.scopeChain, f.scopeChainFrameIds)); + + /*TableModelListener refreshListener = new TableModelListener() { + @Override + public void tableChanged(TableModelEvent e) { + Main.getDebugHandler().refreshFrame(); + refresh(); + } + };*/ + TreeModelListener refreshListener = new TreeModelListener() { + @Override + public void treeNodesChanged(TreeModelEvent e) { + Main.getDebugHandler().refreshFrame(); + refresh(); + } + + @Override + public void treeNodesInserted(TreeModelEvent e) { + Main.getDebugHandler().refreshFrame(); + refresh(); + } + + @Override + public void treeNodesRemoved(TreeModelEvent e) { + Main.getDebugHandler().refreshFrame(); + refresh(); + } + + @Override + public void treeStructureChanged(TreeModelEvent e) { + Main.getDebugHandler().refreshFrame(); + refresh(); + } + }; + debugLocalsTable.getTreeTableModel().addTreeModelListener(refreshListener); + debugScopeTable.getTreeTableModel().addTreeModelListener(refreshListener); } else { - debugRegistersTable.setModel(new DefaultTableModel()); - debugLocalsTable.setModel(new DefaultTableModel()); - debugScopeTable.setModel(new DefaultTableModel()); + debugRegistersTable.setTreeModel(new ABCPanel.VariablesTableModel(debugRegistersTable, new ArrayList<>(), new ArrayList<>())); + debugLocalsTable.setTreeModel(new ABCPanel.VariablesTableModel(debugLocalsTable, new ArrayList<>(), new ArrayList<>())); + debugScopeTable.setTreeModel(new ABCPanel.VariablesTableModel(debugScopeTable, new ArrayList<>(), new ArrayList<>())); } InBreakAtExt info = Main.getDebugHandler().getBreakInfo(); if (info != null) { @@ -325,13 +397,13 @@ public class DebugPanel extends JPanel { varTabs.removeAll(); tabTypes.clear(); JPanel pa; - if (debugRegistersTable.getRowCount() > 0) { + if (debugRegistersTable.getRowCount() > 1 /*root*/) { tabTypes.add(SelectedTab.REGISTERS); pa = new JPanel(new BorderLayout()); pa.add(new JScrollPane(debugRegistersTable), BorderLayout.CENTER); varTabs.addTab(AppStrings.translate("variables.header.registers"), pa); } - if (debugLocalsTable.getRowCount() > 0) { + if (debugLocalsTable.getRowCount() > 1 /*root*/) { tabTypes.add(SelectedTab.LOCALS); pa = new JPanel(new BorderLayout()); @@ -339,7 +411,7 @@ public class DebugPanel extends JPanel { varTabs.addTab(AppStrings.translate("variables.header.locals"), pa); } - if (debugScopeTable.getRowCount() > 0) { + if (debugScopeTable.getRowCount() > 1 /*root*/) { tabTypes.add(SelectedTab.SCOPECHAIN); pa = new JPanel(new BorderLayout()); diff --git a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java index c951dd3ce..5869e2ecb 100644 --- a/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java +++ b/src/com/jpexs/decompiler/flash/gui/DebuggerHandler.java @@ -22,6 +22,7 @@ import com.jpexs.debugger.flash.Debugger; import com.jpexs.debugger.flash.DebuggerCommands; import com.jpexs.debugger.flash.DebuggerConnection; import com.jpexs.debugger.flash.Variable; +import com.jpexs.debugger.flash.VariableType; import com.jpexs.debugger.flash.messages.in.InAskBreakpoints; import com.jpexs.debugger.flash.messages.in.InBreakAt; import com.jpexs.debugger.flash.messages.in.InBreakAtExt; @@ -108,6 +109,40 @@ public class DebuggerHandler implements DebugConnectionListener { return breakScriptName; } + public InGetVariable getVariable(long parentId, String varName, boolean children) { + try { + return commands.getVariable(parentId, varName, true, children); + } catch (IOException ex) { + return null; + } + } + + public void setVariable(long parentId, String varName, int valueType, Object value) { + try { + String svalue = ""; + switch (valueType) { + case VariableType.STRING: + svalue = "" + value; + break; + case VariableType.NUMBER: + svalue = "" + value; + break; + case VariableType.BOOLEAN: + svalue = ((Boolean) value) ? "true" : "false"; + break; + case VariableType.UNDEFINED: + svalue = "undefined"; + break; + case VariableType.NULL: + svalue = "undefined"; + break; + } + commands.setVariable(parentId, varName, valueType, svalue); + } catch (IOException ex) { + //ignore + } + } + public synchronized void removeBreakPoint(String scriptName, int line) { if (isBreakpointInvalid(scriptName, line)) { invalidBreakPointMap.get(scriptName).remove(line); @@ -332,6 +367,17 @@ public class DebuggerHandler implements DebugConnectionListener { clisteners.remove(l); } + public synchronized void refreshFrame() { + if (!paused) { + return; + } + try { + frame = commands.getFrame(0); + } catch (IOException ex) { + //ignore + } + } + public synchronized InFrame getFrame() { if (!paused) { return null; diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 3809ce7ee..fcd4818fc 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -519,6 +519,10 @@ public class Main { loadFromMemoryFrame.setVisible(true); } + public static void setVariable(long parentId, String varName, int valueType, Object value) { + getDebugHandler().setVariable(parentId, varName, valueType, value); + } + public static void setSubLimiter(boolean value) { if (value) { AVM2Code.toSourceLimit = Configuration.sublimiter.get(); @@ -1394,7 +1398,9 @@ public class Main { @Override public void disconnected() { - Main.mainFrame.getPanel().refreshBreakPoints(); + if (Main.mainFrame != null && Main.mainFrame.getPanel() != null) { + Main.mainFrame.getPanel().refreshBreakPoints(); + } } }); flashDebugger.addConnectionListener(debugHandler); diff --git a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java index 4433e28d7..57f6c2a79 100644 --- a/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/abc/ABCPanel.java @@ -17,6 +17,9 @@ package com.jpexs.decompiler.flash.gui.abc; import com.jpexs.debugger.flash.Variable; +import com.jpexs.debugger.flash.VariableType; +import com.jpexs.debugger.flash.messages.in.InFrame; +import com.jpexs.debugger.flash.messages.in.InGetVariable; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.abc.ABC; import com.jpexs.decompiler.flash.abc.ClassPath; @@ -38,6 +41,13 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst; import com.jpexs.decompiler.flash.abc.types.traits.Traits; import com.jpexs.decompiler.flash.abc.usages.MultinameUsage; import com.jpexs.decompiler.flash.abc.usages.TraitMultinameUsage; +import com.jpexs.decompiler.flash.action.parser.ActionParseException; +import com.jpexs.decompiler.flash.action.parser.pcode.ASMParsedSymbol; +import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser; +import com.jpexs.decompiler.flash.action.parser.pcode.FlasmLexer; +import com.jpexs.decompiler.flash.action.parser.script.ActionScriptLexer; +import com.jpexs.decompiler.flash.action.parser.script.ParsedSymbol; +import com.jpexs.decompiler.flash.action.parser.script.SymbolType; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.AppDialog; import com.jpexs.decompiler.flash.gui.AppStrings; @@ -66,6 +76,9 @@ import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.treeitems.TreeItem; import com.jpexs.decompiler.graph.CompilationException; import com.jpexs.helpers.CancellableWorker; +import com.jpexs.helpers.Helper; +import de.hameister.treetable.MyTreeTable; +import de.hameister.treetable.MyTreeTableModel; import java.awt.BorderLayout; import java.awt.Cursor; import java.awt.FlowLayout; @@ -82,8 +95,13 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.io.File; +import java.io.IOException; +import java.io.StringReader; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.Objects; import java.util.logging.Level; import java.util.logging.Logger; import java.util.regex.Pattern; @@ -101,7 +119,11 @@ import javax.swing.JTable; import javax.swing.JToggleButton; import javax.swing.SwingConstants; import javax.swing.border.BevelBorder; +import javax.swing.event.EventListenerList; +import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import javax.swing.text.Highlighter; @@ -263,30 +285,167 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener tableListeners = new ArrayList<>(); + public List path = new ArrayList<>(); - private List vars; - private List varIds; + public Long parentId; + public int level; - public List getVarIds() { - return varIds; - } + public Variable thisVar; + public Variable thisTrait; + public long thisTraitId; - public List getVars() { - return new ArrayList<>(vars); - } + private List childs; + private List childTraits; - public VariablesTableModel(List vars, List varIds) { - this.vars = vars; - this.varIds = varIds; + @Override + public int hashCode() { + int hash = 3; + hash = 53 * hash + Objects.hashCode(this.parentId); + hash = 53 * hash + (this.thisVar == null ? 0 : Objects.hashCode(this.thisVar.name)); + return hash; } @Override - public int getRowCount() { - return vars.size(); + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final VariableNode other = (VariableNode) obj; + if (!Objects.equals(this.parentId, other.parentId)) { + return false; + } + if (this.thisVar == null && other.thisVar == null) { + return true; + } + if (this.thisVar == null) { + return false; + } + if (other.thisVar == null) { + return false; + } + return Objects.equals(this.thisVar.name, other.thisVar.name); + } + + public boolean loaded = false; + + private static boolean isTraits(Variable v) { + return (v.vType == VariableType.UNKNOWN && "traits".equals(v.typeName)); + } + + @Override + public String toString() { + if (level == 0) { + return "root"; //TODO: localize? + } + return thisVar.name; + } + + private void refresh() { + if (path.size() > 1) { + path.get(path.size() - 2).reloadChildren(); + } else { + //Main.getDebugHandler().refreshFrame(); + //InFrame fr = Main.getDebugHandler().getFrame(); + } + } + + private void reloadChildren() { + InGetVariable igv = Main.getDebugHandler().getVariable(parentId, thisVar.name, true); + childs = new ArrayList<>(); + childTraits = new ArrayList<>(); + + Variable curTrait = null; + + for (int i = 0; i < igv.childs.size(); i++) { + if (!isTraits(igv.childs.get(i))) { + childs.add(igv.childs.get(i)); + childTraits.add(curTrait); + } else { + curTrait = igv.childs.get(i); + } + } + } + + private void ensureLoaded() { + if (!loaded) { + reloadChildren(); + loaded = true; + } + } + + public VariableNode getChildAt(int index) { + ensureLoaded(); + Long parId = 0L; + if (thisVar != null && thisVar.vType == VariableType.OBJECT) { + parId = (Long) thisVar.value; + } + VariableNode vn = new VariableNode(level + 1, childs.get(index), parId, childTraits.get(index)); + vn.path.addAll(path); + vn.path.add(vn); + return vn; + } + + public int getChildCount() { + ensureLoaded(); + return childs.size(); + } + + public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait) { + this.parentId = parentId; + this.thisVar = thisVar; + this.level = level; + this.thisTrait = thisTrait; + } + + public VariableNode(int level, Variable thisVar, Long parentId, Variable thisTrait, Long thisTraitId, List vars, List varTraits) { + this.parentId = parentId; + + this.thisVar = thisVar; + + this.level = level; + this.childs = vars; + + this.thisTrait = thisTrait; + + this.childTraits = varTraits; + this.path.add(this); + + loaded = true; + } + + } + + public static class VariablesTableModel implements MyTreeTableModel { + + List tableListeners = new ArrayList<>(); + + VariableNode root; + private Map> nodeCache = new HashMap<>(); + + protected EventListenerList listenerList = new EventListenerList(); + + private static final int CHANGED = 0; + private static final int INSERTED = 1; + private static final int REMOVED = 2; + private static final int STRUCTURE_CHANGED = 3; + + private MyTreeTable ttable; + + public VariablesTableModel(MyTreeTable ttable, List vars, List parentIds) { + this.ttable = ttable; + List varTraits = new ArrayList<>(); + for (int i = 0; i < vars.size(); i++) { + varTraits.add(null); + } + root = new VariableNode(0, null, 0L, null, 0L, vars, varTraits); } @Override @@ -310,17 +469,21 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener getColumnClass(int columnIndex) { + if (columnIndex == 0) { + return MyTreeTableModel.class; + } return String.class; } @Override - public boolean isCellEditable(int rowIndex, int columnIndex) { - return false; //columnIndex == 2; //TODO: edit variables - } - - @Override - public Object getValueAt(int rowIndex, int columnIndex) { - Variable v = vars.get(rowIndex); + public Object getValueAt(Object node, int columnIndex) { + if (node == root) { + if (columnIndex == 0) { + return "root"; + } + return ""; + } + Variable v = ((VariableNode) node).thisVar; switch (columnIndex) { case 0: @@ -335,24 +498,157 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener= 0; i -= 2) { + if (listeners[i] == TreeModelListener.class) { + + switch (changeType) { + case CHANGED: + ((TreeModelListener) listeners[i + 1]).treeNodesChanged(e); + break; + case INSERTED: + ((TreeModelListener) listeners[i + 1]).treeNodesInserted(e); + break; + case REMOVED: + ((TreeModelListener) listeners[i + 1]).treeNodesRemoved(e); + break; + case STRUCTURE_CHANGED: + ((TreeModelListener) listeners[i + 1]).treeStructureChanged(e); + break; + default: + break; + } + + } + } } } @@ -650,6 +946,7 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener(null)); if (dpos > -1) { decompiledTextArea.setCaretPosition(dpos); + } } @@ -872,8 +1169,10 @@ public class ABCPanel extends JPanel implements ItemListener, SearchListener