apvlv-0.1.1-Source/NEWS100644 1750 1750 13267 11521211167 13703 0ustar00pengdapengdaapvlv 0.1.1 =========== News features * add '[int]s' to support skip some pages for some document apvlv 0.1.0 =========== News features * UMD file support * using CMake for auto build tool * add rpm and deb installation package =========== apvlv 0.0.9 News features * More like vim's info file schem * Add `guioptions = "mT"` to support menu and tool bar * Add command bar response when command is failed or command is not valid * Add double click action on pdf pages for select a word, a line or a page of text * Mouse Copy Support: add left drag to select area, and right click to popup menu to copy to clipboard * Key Copy Support: add select area by pressing 'v' or and copy area by press 'y' * add 'wrapscan' options in $HOME/.apvlvrc * add search support of dir and content view * add Startup.tex to source tar * use \ to support space in file name when :o[pen] or :doc * use 'G' to go to the last page * keep search direction when search with 'n' or 'N' after / or ? * add autoreload parameter to support auto reload document or directory view * add reverted pdf page feature Bug Fix * display '*' when input password to open pdf docs * return false when search next but no first string was be searched. * return true when sub child dir has pdf files * fix a segfault when yank text * fix a memory leak when destroy a apvlv doc * fix the correct select mark when scroll up or down the page * fix the k or j 's length in continous mode apvlv 0.0.8 =========== News features * add DJVU format document viewing support * add poppler-data support in Windows version * add :w[rite] filename to save document * add zw to fitwidth and zh to fitheight * made the scrollbar as a option in $HOME/.apvlvrc Bug Fix * If a pdf file is not entrypted, not ask password when can't open it * heightlight correcly after zoom in or zoom out * :z[oom] fitwidth or :z[oom] fitheight works apvlv 0.0.7 =========== Changes for WARNNING * apvlv don't support negative integer now Because the '-' cause many bugs in in - to smaller a window, apvlv don't support negative interger from 0.0.7.4. News features * add shell command line options, -h, -v and -c * add options to disable ~/.apvlvinfo * add a option "set autoscrolldoc=yes/no" to toggle auto scroll a doc from end to 1st * add a option "set pdfcache=[number]" to set the cache size of pdf object * set pdfcache >= 2 limit for apvlv works correctly * set no autoscroll and not continuous when pdf is a single page * add global /etc/apvlvrc * don't create ~/.apvlvrc automaticlly * made fullscreen really works under some WM * add key 'n' and 'N' to search and back search Bug Fix * fix file is not exist segment fault * fix the command histroy segment fault * add document of / and ? key which appear from 0.0.3 * fix lots of spelling errors in Startup.pdf apvlv 0.0.6 ============ News features * Warnning !!! change 'goto' command's 'g' to 'G' * add continuous view of pdf page set in .apvlvrc "set continuous=yes/no" * add argument to support weather auto scroll page when k,j to page's end or head set in .apvlvrc "set autoscrollpage=yes/no" * add Up and Down key to get previous and next command in Command Prompt * add tab view add :tabnew and 'gt' 'gg' 'gT' 'g[n]' command to support tab switch, change goto page command from 'g' to 'G' * add content view * k, j to select up, down * h, l to expand, collapase * open selected page * 'o' open selected page in split window * 't' open selected page in new tab * add direcotry view by command 'O' * k, j to select up, down * h, l to expand, collapase * open selected file * 'o' open selected file in split window * 't' open selected file in new tab * add goto a heperlink and to come back * add open entrypted pdf with password support * add open last directory * add mouse wheel scrollup and down support * add a padding argument to continuous page * add :number to goto page Bug fix * fix the windows open bug * fix the keys can't work on 64bit platform * fix some segment fault * change the width, height of apvlv can resize apvlv 0.0.5 ============ News features * add cache module to make the display faster. * add ':set [no]cache' to tell apvlv if use cache module. apvlv 0.0.4 ============= News features * remove the status bar from the bottom, and add it to every window. * make the active window healight the status bar. * add 'r' command to rotate page. * add ':TOtext' to translate pdf doc page to a text file. * add ':pr[int]' to print the document. * add ':open file' to open a PDF document. * add ':doc file' to set the doc to current window. * support open multiple PDF files once, and load them in cache. can be set by ':doc file'. Bug Fix * fix the absolutepath () bug. apvlv 0.0.3 ============== News features * Replace word which like 'C-a' to like '' at every nessary place. * Support 'H', 'M' and 'L' to scroll one PDF page. * Support multiple window view and support below command to control them. 0. ':sp', ':vsp', 'q', 'quit' 1. ' ', ' q 2. ' k' 3. ' j' 4. ' h' 5. ' l' 6. ' ' 7. ' -' 8. ' +' * Support multiple PDF Doc to be opened at the memory. * Support map command mode like 'map a :vsp' apvlv-0.1.1-Source/ScreenShots/apvlv-0.0.6-9-dir-and-content-open.jpg100644 1750 1750 252371 11521211167 24047 0ustar00pengdapengdaJFIFHHC  !"$"$CX "Y !1"2AQTW#7Uau4$5Bqw3R%brVs&CScv!1 ?YEFdÌ{ lZt6uDzݱzp-ʯf vxvov^죇sg{m^? 1?OOvewqVw e;b<=E-wR>6Vqr)˛nI"t4 mcZW2O.[$[fdrpΚJ_b?ݷo)q/MܔG@!< #W\&dZși*jR9%$J(l/k OS'S\e+N (jS4H!|H$sInu.uYJ+=҄%)C< ): 'SP- [e[sԀ _= )~!R}dg] ~$$<^m|R(IP*@H)PUq hq2T /cdWw#lf}I'Is'RO5Oybf2ˁ8ťAn:R< dr׮SޞvgCZ3&mbήcee.xs=lA*SnKmY!]h-A`%^'u/pxst>q޹Ǭ5!IJhKN,,OABB{:NEwFڧLkMq|DuD(mIR~vgCO;3o ȳt2wl]X[2eJO>*rOuP.M3dv Lc4Ҽ5~Omqw^vgCP\']0=r.]naN; ģl.1hRTTQr=+UlϰWjě0.aj9GckY.8 [U5|O֯P>jf}S૧ٟ`Z~(j}֙-)u81 b-<-$ >C] N95iZfKG#إ2&i ĩ ?$-{(Mɷd5s_)m=m4RRFJ׿Y_^}E'Wm̖Eb2q) |ڸ))lvߩWu]pp[Sp"jmJK6ЀH RT>cwO֯P>iZfK{-E%2c–e!o[\춛}<9h#x#[jZ~(j}֙X٘m[S$~9[y\I],FоG~E'WmQI@3%1XCjPXKIC;óܵ[ nSΣ<4R~z>O^}2[sĹDi!d%O^}2['Q>Zn0ٕlÆs_RUS)*$~PAO֯P>iZfKfϢ?fJg3X_^}E'WmlגGL#fk Z~(j}֙-S>ٚy)DaR~z>O^}%^Jg3O%3/O֯P>iZdkL#fi}5QI@?R~z>Ly)D<Ϣ?f)?Z@huO֯P>iٯ%3GE'WmQI@2[5}4S>ٚ(j}֟)?Z@huKfϢ?fJg3X_^}E'WmlגGL#fk Z~(j}֙-S>ٚy)DaR~z>O^}%^Jg3O%3/O֯P>iZdkL#fi}5QI@?R~z>Ly)D<Ϣ?f)?Z@huO֯P>iٯ%3GE'WmQI@2[5}4S>ٚ(j}֟)?Z@huKfϢ?fJg3X_^}E'WmlגGL#fk Z~(j}֙-S>ٚy)DaR~z>O^}%^Jg3O%3/O֯P>iZdkL#fi}5QI@?R~z>Ly)D<Ϣ?f)?Z@huO֯P>iٯ%3GE'WmQI@2[5}4S>ٚ(j}֟)?Z@huKfϢ?fJg3X_^}E'WmlגGL#fk Z~(j}֙-S>ٚy)DaR~z>O^}%^Jg3O%3/O֯P>iZdkL#fi}5QI@?R~z>Ly)D<Ϣ?f)?Z@huO֯P>iٯ%3GE'WmQI@2[5}4S>ٚ(j}֟)?Z@huKfϢ?fJg3X_^}E'WmlגGL#fk Z~(j}֙-S>ٚy)DaR~z>O^}%^Jg3O%3/O֯P>iZdkL#fi}5QI@?R~z>Ly)D<Ϣ?f)?Z@hun>ueK| RH*h '}О$P)DtJA:rLXSϾHHږHO`ceI.e*j?+ï3nl0nAKIۊV5fo֏'՝UO?}Fh2}Yq%)JХ)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@&q.,1:tbč1}i HO`NF7aV\& <@Z'0BT'yV3'{[lY/LZ OyٟK RT/~mtReAއK~δ>z7GΫ)JV)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JBp?hT֡YOcZ*}65Jyu]UJyuL5ko֏'՝UO?}Fh2}Yq%)JХ)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@)@VS.֊+)oEOæ_VC.«_VC.©~~:d߳O:>$)Z(((((qrg|9HqHmJp'h?-I+TL%|O2T 37ߕ.2um!cPx)m .z ]mʈa2`:/$$ Y QhWnۮVަ.䥢[hmH*Oy'kK[9ܽś-%N2J[> !Iq%|B=O%S\q4 7c J JgT@bnAki) s-HB[P+RGr++~-\}ԅ;9y-%KCFV@ ogȥ/6^0Y2VVg koEf|(;m$xJD|/tr\'8eK`nC҈fLDYOH֗ヨT_vED_A @H$trY(Q)p/b>F~7x蝃|>Ey9rdeŊχjث@s#J4ҫC->ƒ=|Bme6G:jBvvx/h[y)9J׭ ǗCK.:7[V=:?!ub+ZN $( m1A$:zPEcr&&n3mL Ze77*:;wڳ9'T1kɔLI(B pA$$kT@aې븵ol-~!SgF\{UԌ$s2; [_ J*Z̷N/` ٘.3V;DEp9R⺇XBl$'(ֿZw֦A-?.~ Z|R\ |$[! J96S@;[mnkP5_S$͉]7Km )RN k{ݠs?e2ƐO !I?Z!HWw,vLeDLs~]2$0ۅttG`;mgdf:L[ u:YIQKl'j 'dhd}mսyYq1Ǟ<x+䨏]1}\$=d}d|xq^.Pqa:HN:Yr1w\jTyf425 (BPlˬ\P$HE 0ZH,W,ˎl^qMC>oZ`.Y#o7;ɄK*|RRP A:Ie춨1j.t[A,[QBB!*?Y<W ?Y<W 7GΪǧ~δ>hRRRRRV.~u]h) :)IJD9YPFb`XIVIQ̴ Ej%t,(J ̓"y ҚRuM8A)ZHRU߲u(#10,V>3'5r-&TʔHx) 8\Zmʏd5_e`e6ŃjW(WRIBRV6{܎҃ m1t D%;~[ZqIq _%J]pI#XM0L֗䷃[De崕(]RPy@f&V:S-\Cee]w=o.l I ).I˭.đ-Bc헓4+RH lĹhKo.,-8R9ώ&5/N9p&:-kyGp9r{h&n8?*6,eeIZZYAR '%?^Pxo֛u&v$4TR7l~J1ŕgՕ)BQ (oQE*HP);jV[a\a5hXy}ٞ8G /)DN~uwF̷ِUȠ7ဓsm(:(gKi$7h:U++|xF3AJ|"#CIֻzT֔ =hr JKT$J꒔w=!=nՌbQ2KEͰ<_A[R7× Vt6NEJdI&BJt%ARW{44{Wǭ8ͯz7GΫ)JV)J)J)J)J)JW}e꽟K 7&sT"$)JHRNl׵X_1oq9t)H31ʤ!iKdT;QQ;~l[eo!;&z!C@@%*ByhT WCii-Pņ۠p(q[Z,.2;n?M+1U\h4^,)Aj/7;Mwq~[a,OjY;J[@'il==($}ac"7LTd4︑iRGu9=."c\E+*TPc.q F{=C0~LL)ŶZ*oUS[voٮ|< {[<߆eC~ahan\we3mma!6yn3)#C G~'{,ml->NyUKIK>6GrܙmxB2Lvy eN[O4B Q{@}1KԌuo+e[\A$%<ϰ9/ TdwFEnSlG4"Luͬ$e`p2r XW;֒BFgh P.޲{;s˶ĵrP)oJֻ6޾uD`ϠJx R kug-#mJ߂wK([9N=k-2;ɒY}I3#\G>6}=5|)*oQ|ET?ZׇZ=^f6#d{nRUonQm-%dk(z[QhuFq/6|)[b9-Q-B5~;\+GOoaLM}Uŋh-H,Ɔ`=Ψ+/UTܭ{Vӥ)!h ?ǺwOv$dMO\#>Nԡ^W^=R:!sW,͹ǽb),B-TA#$W^mdy%˥-XĜruIooędVV҇7IO/~d\ZfyWsSa.LF2B=L?S3r_rRpU_g=|X5 BL"ZÅŅ%`Mr:Wt8]M-G^'k._JTL9HB0JG*H:Q vw%+@!.-((R C]]Ul.8)8yeZ:JJNzֵt9jQ.I%CQ۽qfh{pQS!*pKثv*ٸdDB*\$oPZR}vIŲ`(ǮQsĹ-ݛ ږX%!={w+=sNGcfHLžbTR ˊOkU\ɹ?Qrv'i?J.%<ŝr~ av}e4eύm.ވDiI% m?=f]=%}1XQS%@*ϧYf:D1Oӗlߥ9QէM]nk :Jk!<Nj\̛ gm7ihY<@N, \n"FRP[Knza$ZQ*Z Vn_Y1 QL˫#قKꊤ%RႴ{z5O*?Hzr.|!FWa5V )$D) cK܉)dțr;^rFѴ#Gw!b_\,(QqB FDal 7G]D/>*Iz7GΫ)JV)J)J)J)J)JT]Dy]KvTU\Ȳ8(Ҡ qjkA 'ztvӞZp^aGƑv1Q<Ȑ YIHY6SǶSᗌr~Q~²x[m * 0S+Q@jǥMNOQ#e gX$m3>q{^:RJAַSl&٘[,e\QkGu[˾:PSHr $8TeHQPG!,oAzCk̼F4 t)j犸)(HJTwJ{S4QQ--F Q\7Z7Y*RZunwu#v$,۩ 2VÁc 4{҃V:]ZF/Ď[f܉mi-T]4Ocּqu܅f\$2ZBRT ;ug҂agRY7KƨNPkplk(cHm(iTCm(5:sޣ5乾PoTIbn):u!q{ī; 稝*|͂Ә,q:@TR:JN54zb+NȍwvyrPȨ <(:z}X&#[e>쯱3)[:Z(OrI5f҂'uSt eq,aDT%e! Əzt˒3KS3 hLBjk܇ SyCukW" YmۥW y13*i ;}`z̑5Ћ }MFʣ ٫VJWZxJ&\ 32Im%>АNw>2.`6W,˻1Q*yQ{RF J ӯ֙q,r%&Q]SqS[tl@z/9[0q+Kv-q.}t`WAHK 'nKտJ u=`zƥz9*)HhJ2jL)w!)sɘ\C.IzbAm6bBd/OũN)< ADj/&kf7 -JBQR`*dFoՏ1S uTK>T{{E%XZ6R(ha*ҥ((((((((((((((((((((((((( SZe?~эht+AUuU+AU0կQgZ?̟VuV=?ugUĔ+BYOcZ*kP\1>?Y<W ?Y<W 7GΪǧ~δ>hRRRRRRRRpu*tA:Wi}N$- BA)Jӭ:Zq\T=Ab(#`?U(i+( IO@pm֜[m-m.%*:@|B%hPRT6;|JZcRy6$Cc~b }8x6׈9'FI;)_BRTd֐[H J;AΔ!A%@( 5wP)_9'G! JP$4 Q$($pG\u[8m%KZR$ t$0p0nx+@::#@|JP:::>Z!A|M({ݷރ+T A@;q:R W¤[ ll%IP%* i\\ZA[J=J,aC/Je+u`Vr)uG)JP)JP)MRJWZao6 -T=N7R WmqiBvt6N Waiql!ԥ@Rtt~BAJQ_,,qGkG{ևK+B)RNi\K-eĄ|=]ʁJIHTɠJQ\I?05#[ llI*) QsG?Aʕ BiVtwʁJRJRJRJRJRJRP\15VS.֊MMR]WUR]S Z?ugUcQgZ?̟Vu\|IJR)JP)JP)JP)JP)JP)JP)JPW[ twi†-xZ”!*cԥ "NR$a9fgbE(\Z]m2Y!;Zj崫~vxʚ]upCE4x}k{FI3-0LUS!*>wCT~Z٬wۤ`P͈%9dL`P.Ǿ+"rɶlVd8)f: B sm/*HqA]734ĹZȊ2&/i-iJ8RNt*iquWee֮nΡ(_(AR.w#=Nn߲3˵~Yi>a v[*[V=Dn?u\6^8k 'ZP*pJ)@JS?XZ[\ t{?ie<%Jie Qa-ypcLGo5t%N . 4uJ 7J$.keU"{~dT(xԆl,ZH=1wp!LG˼l, $Gb5ڃ\pB.X$cRU1Oqd)ΩĠ,~~_ be'I?vhlܵ"ggDmhhl,%H:#'tsx7I|uϚ}նqZZ`voOo,+^:͚Ջ;ꣀJJCjR4-2k\D|zprm_ž2ی6HZpO e#ao,Ϟ"ц^2[ͦ{;ez1%(x⯸W?y:'[k;w6=ԛ.tLmM6JN{:WStYc"nDޭ}]<> \}7c9 ɑQg,ڊ6-)J7mΧ2BL]JGXG@lAr(d| c0$9('v}+it.Z'H jF$5+p|P $4ݲ>W2-rg%1=Id,<}蚬#0贳/, li43//o% DvU~x=͕ކl[6?ckIrDN>-B};EEdzTs">_zfQN 0VP m8 ‡%,{jt!}*>N1ej -,%h! 'g'j*R-HvXo\B!#%䅲U%6qD$G["p-Ɵr.Rӌ:$(IPh6Q',falv뼋6Z(?^={{7R-%ڟrlP@ԠuotzG4.zrEx!ԇ.V9fΡZ8K- IK\O.t:e&U]p̍@zjONAbюZ')W;8\$n:8KM,,,t$ h էLB/._%)L3SNNx͗޼.!8FQXd7=WlUf-2>iԲ|yԺl<ҋIUv6ChUn 80/SN%e^-H۩mM iDq?.^J2G/ȿŋ~yX|Ft2 ␄2K' X +:|Ƌ=aj섹 "&I$CiA--NŒ] ntSG֋zfM9;҄kl)XC}/~^&Z6UθfFJٟrr`/<ҕx}BcctQnJ1-8_~ZқRS-eIm)JXHk'Uc6:IzM%Pp Dݴ4a~s- ĶǗJ.<T;%dqڎ5?oɺ~VAtl{B} BBRNR׻d_\.=Z\>  c9"=l-.),>>.$׿_Zf8rKe\.BPxAmb(+;WT#Aff&9dۭHe1Jq IHOƱ,2"\霉Fs r󐭉d τ+w>MZO2͋v}h%.9%%$KsT6<˵Ŀ˴³hMyNqImY<>!+#DT>mRE=Znuc/9 "Ͳty1opSŧҐN&RgjvؠV&n"GȦhb^/"5τΓ Pz[m lXSfd.0O4\ P%\J8>?ᗻ=c0Fm;,9 b"덗y>+%$ 'gUyt+o[^\/%jLY䧟W$ſx{屣 jٮ'ƴlĸJv b[ )ДFԟtW׼T򨖷qs7,c!bd).CЫ~k!{-V۫zm,(VNJ@_wy`vuCwViUEao[r!u|+K'OFKv;G~YڗɈ )(J<[% .'qȟrDŽˣZƾ) OtC=C}>?~mvmv}~i)- (ԱDIɧ@lR Z5\R4;*HF?Gn Qܧ!-L(%n?*U'^@IPUO?ow+3#ͶD?Y<W ?Y<W 7GΪǧ~δ>hRRRRRWV% G@WڥsHȇQ-oN&ĆT/GT8TR̈(pkN%}Hk#Boy̸-,GZ;$S\ZqC8ZBAEF"y%~y4ۏ:G+iwխ2wJo&ڮ$X-2OesZHJRN RV J$yV+ӫ-az|~ޗ">QqSϼ[\H:y+Ce :w>PF;IƧ!ON!ShA(IRܒt}y%embt7hFɒ'cFB^S-!JbkэNe9VPFښ7W*ڸۀX Gꐑ(%R+M/C=?/665n8/xlXB滋dՋnn@ܳ!&RGÑCi)ׄ] qdhpi`nu(APڵbo[jQ̛n{Uਓ#h. m6Agc[Sk}wȬ.xkʹZz3#enrK( )iJ(}Nڴ/[`ʅ _ʁ \o=oH\)["P`ϝLDv[㐗rg9V[uLog[ uTIAP5E[q[-1- DJ:W6|Խ^檻!3²\WZISHtNe.IF;r74NC*(QJ҇?V?s\)ξM|%1Թli {:`- OO -Sm K-:#ֆ )s{A!.6 I;Wϱ)i[?XLzWtPJPHO}KeNCpsyQr O"8dokMriL3#%v.^oH[E%5vԝ ]atA?04qP#g1caoc'JfۏMF}Z^K/o oRww֢Z_\d,6R3Ɏ܈.-PRV6#|dpkIZU@ٝw 0 )Z>bnHB3.4~o쯑:;vbgpK| xZ|t7|wzemDNIÐ}Zc/&[lP[b_Ln"#T*T#E)Jˏ~ĊrՊ)II1&ɖ/>*|P~0m*9R @g_:6l-LIJk,t4]rQJRI*Pp%.aeCB@ .'}}棲u 4J%)Ԓ}SoMӧńWmIu ) G`GbzJ:>co1%v? - ~+um.'+Gz!}P\k(:nq(~DFoa$jCe#riM?e7LR,\縖!4NG (RU_Z%*IRN>^Ve{lDerdVΉ1HYm%XKJо$)#H7u COKa @ [Ac8eĘ7\o^;:[N#ͥii Fpx\H:#GbkؕkbUvŭV2ZayOR@#; RU*GGG֣fDFn)kMjT {Ey KKix-QHNs:"ݗ_%]nKd~>P@qKj)N,A!ֈlCJmwIRT6Hwv5ש0ðEiFppJb3O%3/iT\l kҧǞ#55ۥtr5N}ҕQtrk䠴└'>ru_j;ټsbjyR*2Ծ\Ӥ ]Z4$SZ+8A}|s]wXŒ%+mq\T %C)&c33+ za9^$-q%AhV[ C]l"tK|kÆru޵^bbV6d*퉐^G5if1WIQ#DJȽJ#<$ڜ;+$1ne)w{mA]CHP JJJBQA>[ֵ5,{\)$6jz ]̅%Ex!:b2hnđa+Z.GC~kX(ejWay.,65G#~ o#oz]o^CU/,-4=դȕ]j)7;[r%ʌ0bj$yI v.4(snBS7{6ҕR ش+ /ݤ͌j2O)|E%. yqoZ+8Xf w[žsn?$le$kZHJVP #}>5"KͶ5*oe]\#WLBxJJ7ፕ 6,f^tCܗfv-R F~F~DFֆT]ӭ:A}6N-6PttAs;ɮ/sɷ ;n0!j}?%NhVI6 ]_Ylq^|en)l<껤kj?-%0mV6PRT>pGc\'Z޷U]>~n lW=qTlSe\HE۳Zio?ֳ`g="vk96Sz6ʼ}L*6P!kQI?08%Iڥ:+.EX\͖d>ˌKT%iP[%eGٺ(((((( SZe?~эht+AUuU+AU0կQgZ?̟VuV=?ugUĔ+B 3\& >#>a.+RДVpy֘liT6NsNѻV [b~E~wi3y  $)zO&Γ%$l,>-tndWļ *iCGW)hJ) S*)IIHR*:>փ WcZ0֕ ICPqS nWCM^l5 ɖ.6J p{ĝqrRGNm vNsϵKqs9G6hW0Ip ^POc}#ۮ ,8VsI*UHL ^[|dHV]HH$IEua ej>+VYNr[5%W˄bxѻj_r^ H#|aRzfn'91םzijaBSRSgV L%2ٞ< r |Ku\BH$%(w6z"F͸ķE5O|Eǘ%Ji**+@Xl!j[?\9JtJp1.xڔ5n8ŝ(.AZZ 3=#K, uKhc\bB-Z`{U i%IPT6Fq R2mI[8#Ԓ{A]c],l﷗gߕR5K%i^6T5۰^@^$YAfnLi,J"K)bG岮D0OB;|5Qxoy',/{B ' H:@M&TRj8iA)aր_{Ҭ #G4V7ւ'],Y؅{iQնɁ%'_5/E[B{ޞυ/,L9"3|taA(訁fZam. m@)zuUܓ4i{4kty-ˎ\KI'=ۍEl$˭r ޻[Umy`8Km+t H*'],*e8P@P:#s`qМvB$C2֤GqquGvuߧy"6L,Qouo⬨cZpr}M`TPe 84)PaAű̮mޞ,˭.Q"EpњHX!6AeG?@{oCo1!'arNȄy~jS+H9O-oHI!IФhPRT6;Wisy6Z'@wI PE\8]`@~,Yodm44e9#4#425dSrxVir-PN޶sڧ)RT6U6>dr^>bGHmL%%iSdkGqYͳ[+c a):J)KTTBGƫ ˝T^K16V-qƜZ K|KA!)*;$zVVoFN2":TZo>}4)}FT^-Źu[7JK䴗YJtHsKCzjwBaGyDxj[J X䝔sR?ɭ]Y]lGqH]gAn! q)R@i7gm'voVl/oEc+B3W j٥-~r&oH7X7.b#iL:ʋM~Dou0,ϝM.x9 q cs lν*_;Kqm%! J@A]tˏ] weA-ʂ$| :}n ֻ-pTf":҉~XRܔ>5߹[TC:G>- dH(~Rju[B[#ˎeGgy)@)@)@)@)@)@)@VS.֊+)oEOæ_VC.«_VC.©~~:d߳O:>$)Z(((((J}cBjweafٞcu:8*kG{U &y5ċV[sm%`, GRfY˘g%]ݺsc[*e%+HO>#jd9nj>wN#Ӥۢ R\/0_`e.4[ s 6([)O4Qw?emܺ? uR ;|&-v2쥐.y +@|Nyɽ3bUtׅ!7!m|qSjp5P;V3?Nm\W{jĥ0fJJJQצ(72bV$Hsbe7WPĩn68xAOʼJ$BjdvssDs2k(*_r`TX.=k[=9vȭ>h ӍKUx2>_f]~ 7;clƒ)s. KG2A PH~5NDݯG$tU M6e&u]4ϧKe85u=w^d_jnx*\rZaI-4C/bV+c0w|bJ|eG$d(vjKkVS2}r[ o4u6ۈ:4Iffu$=^^!-08̭1ѳAl׻[bcsn9DÊ |wCl@lt{VdB]<.L$E"$IQIh7${)y>Cqq GIBTrQ$v Q9DZہjBdF2SrRyEJ=#C MO̢!œ2cz&Nai ө A-j{ܤm3ZX# ~+l'y/@\R~tCb%E$O^)n;4 KI vz1l1KYmX^mҝ;$w_p0mɥUJ$>%)1 -V/q/Hƛt\ru&5QYe '(/JV'#4a;3Bj><[bT<Ԧ˲B]R% @Ja9--fZo6#G\L> dJ)[BJHd)H )Z'}nSJt]t<@D]jm6q謂Y~HW/)d%Nˉj㑒T}SYq)%*Wqe1d>Ύo3vf3c4 8&;Ch!\VPWa"fQ0U)Q.<\nYF#Dy'ZWJ.پixEn"|Vv;M6mh]J|gp:+β<3-W;}]Z[;Z HKڕ{lVX=8{/]nfRHB 7x%-Ϡd,Kz<1+i%R#KlpA'J̃1Ff}PF@dWW]4T!9v]0Zr˾AUDc˺ci:qDO[)Z[M!fO̹Cg~:dۤgPmk攬qH9l%apȭǔꮱ-\~֧diR -/]P^h2 '²e sq!z) 1]Е,{b=N9tI7rSn%B X'z T2;՟\AEڎJ9!N. >C~4۸_ZVPćo‹no R$xzJyҥqlMKO NnP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP*F7 SW˯pW˯pa_~δ>z7GΫ)JV)J)J)J)J)J)J)JGY]5gDvħyOI[^a< ZJy pJ@IZc$gr8:‚CjI4(xY8 KoBC/*3 v)/;H:;1=G}`a&[w7'\o B\t#G@*ڥMp霉W\-DZXңB6V<6ڒTK=_n0 k672eMO)!r:ďAW((/Hۯ9ǬR r ])!JyIH,z&LuJ:SZeN㍣kRV JԒRwSJ>ev,tYSDlG;iq1a! TLRIWqw\]]덡۬{cژE>t.yQYo]t҂IU9qb|~lw8#᰿ rv[Gߺqb{mE0 Xg{zuud҂<$pEP\_׳i =>a+7``"zn`HCY :?J `Kma]B%>"zR (]0رK5Z[==ĝ"ek/+d$@oRcƺhsJٌ\ C cKIq Dgr^QhE +q~(F/lzk^ R R R R R R R R R R R R R R R R R R R R R R R R R R R e?~эhW=QeؒjDwCn+E*5>? ZItwr#!r3<ۨ*ma@5j~/0,mbW>d _mNÂ+R JIJA:B7GΪǧ~δ>hRRRRRRRgt;eJ?F8ͮNr i%(91Fq!_;/0L-CAe&@~"?%Z~ơ/U-W*yvbZeo6!%akl'{w Àfϙ>;RzEvov&r[[K-Ak\_^'"\̰m˓m\̄h{5Y,˭pFf|)LvLt%-8[CӚ$Ͼ4N 7|,rKjc]ʴ6! ;n:2\RPO 'GU-gK[$\d6|ر#-1]uԺAP└v(=tsdN^/L6Cm*BSjB~8V:W*[ɷH(7 ,LI2g07//)AE(u6; Y,d)m` e) 9%Sۏis/֘>20bX .'-Gtpډ"Gz ѐ˻Bw!Njgbt_HCTgDPwR;wžE2 bcIJF8 `65܊F˃vSn֦u` w|~dn6T?Yi0Cxs`M{2VKVydۍ%ei쒡脐H=q_6ǼqrU)HqzS KJ4BE%|7#+Ry c+>Yy/? .Ok{2f1o`ArX0p<8)JR)ED$_EՍ^ߐ iAaC ũޏ*<fԛ{պf0z9}sim8ۈ I)R}!'ыws&eɦIJk.Ɛ-h!T߆l#kW`\  ܮ!-Q>rLi,%Ò{** v=d.r3ʔۑ$n\(c8{i¼UH#N<1cvCvqmbE %ʼP^Ԑ!K^=:} ,ߏCᥤ%8"{A Bҕ%* SdZҫDHG)zMM9q(>jH{ܯ @g!*B3Q*A. €Ҩ6Qm )rmb %V((~ANUDRvTdMja9oO'S3Tjl ZcZ6s]{uqzK9y  $)Z((((((("}\nYV2g3"+R2̖IU΁'[ lChWQ2+D;1h;vqKJJ[*mRR\B㎝;J ![rv 2qs M! %%{k;ǃP2}W k+KzCįke zZ@C2XrH_.a_[* G镹0~T|3@}N2SBH_7@arV=$E<2LIi@Z)\HEy Idѓ}NGJ|$ŖJII!H'dXcjOȭlhrYYJtBOILAAXzW[2*mm΍%>G Rr]`?mn*\;cz䩤!kB w$vݱ}JC F,Y ߚGE*\uD)J[EAM@hTޔ^ݺxf=+ݧ\9 i$H[5N]oBqȸ珪d]1YNHSV݂NjťS7[i̻U_ J4x=ſw1+<~bMDKA+y6m{ZȫZWɫo⃇qJp xLHLiOR Jw~s^ژj߶n*aJ[L۱K W$)<@%y<טCmkKњCE$m.6ZVyi zsh#%2Zk$giCm0T '^(1;WE6)MFPƂKGG`F$vuFq-1[9I 5%~njYJ zWIn7'ǟ uο.OrD&q#q/S'_ewk+K)-nLJ$%kI`) ZG%oI](+lG Z_Feߟ,Q M:Kz_9h9OARŻ_w?ph)ARuW'7b-U~1D x0vv::b; z̧Nwנ,*PUxm.^v#*^%H[n8:x\WH2Hڳڙ-"Tp'JR$T}-YVo<>^7(#~[uPSoDݼܬ2(em1eT/}Wa_ wMb {HH zOAkD5t6 &Kpw;oCҠ~Mnr,MY`;2*kCάIq6HJ$`-P`1KfILy&EͶMDbQj.8{ǖ8^it/Z]2a229.ᰅ{˴BRtIPf,cCm\) iH ?`% *Q%$Yr/_Wnlqop\uNmR4wrJRRRRRRU}oC_ՃUQ WS鰏o_ EI*7կwo֏'՝UO?}Fh2}Yq%)JХ)@)@)@)@)@F՛կ7Z`+Zj!'[eHVfVkMز𮌨H SrgJZm]"uC 4܉`S ڈ$)ͥ7W.v16 J8 _ ں\qWI qR!SBPPE mAJJ5&!V6+/;:ijS;J{!~xf/=GD۹) j<'M260[95"S/rT%'@>-`aHu ^M۪s2tDaxCR>b1L_C6KNׯ{Rt~mPH`ZPRt$|ju7=~Xb/ۗnq _ڢ ZP7EZ}CN.(6V۲VV;i:Rv{hޝi9R``cWy#ʏҕWCi@ȧBbʔ>$ =TY$Vb$I"[êRʃAB9#J DF{u>1nؓryUey-=#E4T842_nP =@kF}clZiM/TT?6{W+a]z\.^)Z6ߕqkE!\[OJ~3h] C1垑>@T6vП}J'|gVnW$K;9#55pjixtQDx6ı\J#ͳ2v`ܒnkNx>!t)B[)mVIY$:ڰ}3![70*e帐O- ޼{VKJ8A͎Ūo-8ts'[ 6dT֤2vR-)-+iN#e@vy1n`9%es!D xoGi Ӌng*KU!M\?2t :<ma."lwD88䉎9)lR}ĕR},7S1S2cWI.L&[a2Hq-+NA- nnnx-(sHW6;6cuod胍|^^yD|$B$)dnbYZ2#0R!!)AZK='T6m]i>QsX :OD>4dKvV%IE 3|r )'F77ϓ2CY}ۃBq) Bր+ke9gIӛW. ؓ쥈oe:iR(ސT{=g{9{feqj3*K} ;q; {(:imf }6ܡ-- Ĩ5!-jli H%:Ogv;7}JTM) m%d )<]vjis.ڢݧ,Z Idl~I)DmECݠtgpM% ۠Jh<)]ԒN4ce6m!WPoO#FZiN+{DRˡXS}nMϏݦ['4 LE*k4>*Gb V5{p["7qaiIXm:BwqHj'HԹkyͮ ηMRtC-DoicUV{R-" ÎҘG;O/~JSksKb5Ͷk _q.y-|)L;<£u2vG{0y6֬rdCC!Q.:_G"h|oHَ;>>*=`:}k"ƐD4E~UZJuykTk Eu2uy:1ɦKuh>4D2!H9_!7GrEC 6o(68[J[{ՏPΒĕې&\gܖaJЩ+)PߪHʽ5bz|^p-lC%d ގ::Z[rrr?f>l.w[Ki!#ݩV"ǹ֑yf^7-e2\ 24Bץ<I$v0ە<Ɵ;*L~mtVm2!Z@R9s>,r,S9p"zV-B+p$XldDzZ_f2\u!ȢlP9%יVᛅEơkO>4fy%gtY 9We!;2Zp Psˋ.m Eű4a*C!~59dw|_$qD8o5jWyZIBq=xgwpu=l6+s'^7QA][m'9%fP[xCƓ d%O(SEʈ{ c٦W7'6wsTt F-ʔTaŝG5ࣚz7GΫ)JV)J)J)J)J)J)U/Q˔KFm2ŘBq"#-0߂ܛt!iO3A]Ja.mIɮrڟPbp)ЊĠy;iTs,Y2(O''!r8)zC+ϰ2%7z7O:L73gn- ݹภ/DYJ?Wz T}@;Sǜ~2T T鎺QbZ콸Mf<9 [WㄔT%]EF[ Z!C\ YVX879-KTT,o#E\mEcφ2#ȸE7NH{ZRێ "[F61{-\fm_Lx2,x% J{"qpyfMwGض\m 6%.҂Rnq}Ҿ^cɌ̱z1&i+/)i/>H=GkdtvMdt80z~K,ʹTJׇzzz?,"2iBTVʖhWFΒRk?.f*Dcf^ef%%8׊%>RVw;4E+\1NfCc(vu\6mFrR<)QZc RަV0̞j[DK]f[(N@$nݥkFų ;.Lc=6*W$%QMR\Tvx+Xp"؉LGZ#-Yi '>SΦ^yąx|f. CJP)P&T2gHʐo殎.NVxQ+Td|R>@A +Zgu3*; x2 *>C?1O/RH=Ȥ^9rαTK(HS.)Jb=PX?eu="Y^u5w`mZcxbalR;gO&;d#"2\SHPR9)1d؞HuS\KnrYb3mi*GG )T67\ܱ2'\d?2de Uنemz7GΫ)JV)J)J)J)J)JQ=W]E\O!:GVKb;aN)JOa/PQ.ij ѐ(\ʷD'd#>*]SKA$(' ZحpDv%!Cc6e^$)l/H)atY֙ wWU3',Ih+t+Cc)ADfkv6l]c eR_t`BF#آL?Vn~## -p:+!I# PS)4\bЛ[Wv\S0꽎Yr8&ծ.ƷM4 .,rv8+'J g~>~:qf /qH*\*[E?OUwfVXQ}5f0ċ[,`}m(rPHNRP`ۧX ͯhRvJR{Te2%2rҋَʎOĔ%(@*RHڒ2=0]}km+G4C~+{Þ+tbXz)q2+UY>zZ-[G/GÏ6y'jRciASd/O噍Z#1ym/%du 3ĤZ𫌾xy1!YaًXB!N)eB]HI NiA $'@r#v12쉲TEè oNܑRNbmZnp$X9Or蒛[^"T{%xR\ViA:yzKz-Dτxf[$yd-( B~9xfʟ™11o8T䣹e(^ƶux҂ ur߈=-96{'> _5D9YR$;l(![RI CpRn?krbߎخ ^6W;P9\qa> jKMw!J B@:X]0ί9\]pW9 4ȻbW.Di\65[QJ _3x1 >f4hheb6[*m]mi;HǸkNXD~+)쫋Du q)q©/(RvC̅M57]n{oLu4έx-)$v߭JmrOd!j0 >)֒xhc eA[ju1 bw$X\\~b9fq}IZh2FygO˧Lr6lǟ{d $Ksy#CVJPk4|z:a&)ăӆֵz V V] 7+I.q,ÎҝH-iPOt%zXI[tt=rtk*&\Gqj}o-mO2O8H I!D1ϰưXٙ)1 1%L[|-,dqP҃R=BgFkkoCarqOkSBK.QHd+BvH3RN{ɻ ̈́(hi!$Đ>zATO/،<(\jR -(4u >!E{#c;uud{'Cke)AZ1W\+l]mZn5ɥ+^*R8 IDv'F::=ƏoGe( ]R)'|،oHrCA˦7_%_t֌b+,6-!5-p{7:h: mIi6KIJoj>1]d\%caC]7%G21+J% y)$&9n}|96O6lI)(x,2 6TTRTt5pR;۳Y-09\!R#Kwւ;:#H* HJ)J)J)J)J)J)JWFW5]X5_u_Pu>F`tT}Z_*aO?}Fh2}YXo֏'՝WR R R R R R :6e YZVIP} $A߭YM>ܲyV>hONOv-)Gm!ZW`CQҞ=&gNUuliO?!6:Ki\] V13 ߬a=FB[ym%M%ĒH#ٮdjsSZ%Zim ]VREF.M0m; %_v/]tppjh(kRAPH$-]fNL'Oq+K {i<"Zt*kW7*clxRI} -” ƦW[ijAW] kI<4S܍5}ʣ@ϝĽY Y`qn,1ID!m (*5O:+:m=~nodh9A--1#e\r KpTnZe]7y U[L3 BOi/l$x~ c1}a74~EIsk2Ў#IBVoiWʪgTY2 N$5qyV6JׄwQ v$K P_n-BԈhA=>pC:Q˩:o? &x"L꜄eT BGmMwaaa_W.{kQ풣ca('[mlV0{ ؽȨmg&(i]}3 K8RyP`q{= 3{-߄iShT"+ϴLXfטGo*q G68AC|=BT[d9ŵ<{E D[0\SA JtgKړh=9OPg߶d1r4E}9|zՎ['bY=VLFr,Y9#͗dR'@_9^1Vm>7o.}wZ#-8!KIW%=MtuO 旨!v!mmiO8-(>A۔3qԦ]nI)TK;+ H҂t~zz\/&:>&:pn5"=6*VԔ! @ L-9O&E~%gJ6EGI}4.Hnľ#%]7"V) m( BR=TNө=_d,WJ$1&LtH)JAQ[8WLnO> lqmEz7[(MË;ZxT yG>lNoH.*9-2\Q {q'; ͛lϯ2LRҗn:xiCii oeDZs;ٷX76z[d-(n>9ix|TPBt)'|k u/ %ټ[&B"$B$t9q\'6x˲j[F/BXq.3o( JJPuш!@L&6=ԫaS? R%8 Z_gk+6wg\{{V R ٙ5wcLZ]gjS қ{A AJTFX;MVP1\o#ad;Rn;|JKk#vBIJAՓ L[{u'AJ\WdˈeBqGJHD WC'.7|[Gl A>6-»$qJamf$ݙAW7*eJAIYWXsqȸݐb3SBQ)'D}t{2,s38Iy ?|߯jxFK0 /y*(v*t ZWVg<=,dZI=OaZtmje~"gq)P".To056@ oւ.=?.L\ƛ-Z\4ctrIZN{OP"%t*1>Vo}d<.N:y k $8*̒-rv_fEEtXm4B)5llكٺsrKW\$r$<59Dkќ*j怕E(lE'6m5zn-&T >;)K~ HpNE&Y%ֱun~<x[W㍴P m J=#ʤZؕ eImrx==eN)FlҏH%5nkyM"ja@.H}HCP.:{!!GM#Ԛv);8rL,-JH65[ށ?NbtQ R?|:SKNl)Cz;B5ǘr6wۛ C4ݐGJʶw8&EiuŜ`AeW"7*а:!n9*5@T(#XVKP[`HTADt%^i ,( ( Hs㨶c޴@ua+"BfBwBPWHVkx.jm"39(?u,F˖OXe,,6[ )KzÃeoػܑ0ū6h(ujAH@ЖUȔ뎃oC7^~WvJm7"*RB}ՍO\o?T[6iαmSo#vtUGiςv J"&cz1̻-xŐ^Ym }II:Q;w?%Wrs"t^jLjwJJG: GvR@٪N 3[݇.1͊¨m)*CN%i RU&ukå߲4Lr=Er JH-rGT@XuR+711\.3mAӑJ ZOiGIR%C][6?o*9oP2R\NIe;RP;&|~k;Y'יK) Q0N򣲏`H s_eŸaL[ `q]^)G@JKqgHBJuFmHKm!(BF@|K}b=%mmΒJPQ}G鷠 ʈ)RDԺ<^h$O˭ԅ]DEq|v9 R3[J('Rw /-M"'!Yn$ 0m ĊR 6JBPJt1~Yr\زTmҞN3a#CzNu1S" % Ki!i%<*SK2RyQİ 2 K'L`G5bΓ3 vfE7u`sXe\Aq m !=T;[ ]sar#6G[jH'mG CރUP՗6{BxІ!ǰNe%K%kBv}˨[L+^=q6yُn4lNu849ȍ _Jb L=C2B£ċ)hqgczg^-/ȷ2NJ4NP Vuqhw5"\Tyyi NqcG7P{)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP)JP*7G7կwg;S M7GΪǧ~δ>hRRRRRRRRV!a?2gCH2פ%~RC'I^Ym?`uf"Ot;Kj[iW'lh ҁOh.UqFQ?6)KWkzZMK8q(%I'Ja=Lg zn"x^w!I2R0H^t6d-%UfHĈ,Va$PQW,jOf˖V\m-.Tv0'R%GAeҨ]8>'eg9"-O4!! Gv'ӱ=+ ce%(K#5᧱YT6@,V{\s+)xpl~t%^)+$qJwVUvzFYm"tw*:R: ڂqJk}^a2s7do\ Ohwϳ%]8D͡)"&H͝A+sn+J>j eS{X1CW+n 7 :xL+Dړ ]S]P]c@8FBěC,C'V4t AjR^ufe U؈\c(ޢLe֋ZXK_Qk#hs2)1npl3 xj!)*pGАU[d)nuĦ3_ ښvH^5!%|R=l9M=ur]|hpyJ[i;K{ AiT6|"^6(QFeWeOI ==@קz}BGl=F1+Ŀ+d(OCjQ)ͥRl^2ȁHSrqjmJue(I<}Hߴ!Caܟv+ .bCjI P$({ o`,Uụ%}-NŇ JcTIK {ji(Xmqړxh02GqJqң+))U{]bś&",nsnMr R#;y_/~)#lޑaULlZ_N"C斠y +wUnaզ-Qno- uS n%Ҽ`e``_"_!5d=KpN5!=/D t˕o1ZȖL1 m!+B׸{eS|N^%6#+QB:=. R=EI}Pi6TJRHވR9y~qBw'_츇T?X$WLި-=7ȯW6Yr]ž:Y%8RӤ{.*U=uVkJ[7Sr,N9\|dn #GM$oDVM΂RyiK-?rO]- \e2Ӗm9x0TKNmIA[NRBT6.:UoDM ^߉)Dޛvۈy KBǢY՞eXOS$oFJYRi {?^NTCNYVI Y\f8.4YÎCC 42tR ^ Sr[GL(q~+cێ8 I)ᣳ [u=&?afCly+$8$aa%U4Gb}՛uZjf^.\#% ED&=7[V(SII)lq#)%2 f,v' U"$ˣH HiKt4 h'z/L pO/x>/{>/Ϸ-է溁u}Xũ5).NiuO5_?z *Ul.ka>AD_C+ˣOIPV{~] UIuql[{ۯJwJ *!wa٧Z`ʇ2cRgE@IB[H*Rd'Z4w۽T)q$%v@QؒkdTB-.CSd0#6K\}J@ APX"եT1|ۥxvbU"IpHJi }wS. yBS561WWTP &UJU6F<,Ja8;׾ζ Hh Otש#Xn)e׭qnZqC!J|-@Q4 +eظ] TuHҒo6+m(ߐRAR}nY d]m7$[cZ -QIߠS)J)J)J)J)J)JWFW5]X5_u_Pu>F`tT}Z_*aO?}Fh2}YXo֏'՝WR R R R R R R R\Z${ۉ q !-RJT@uִG̹;ql9zO}&[pmDV֫vk#gAY2< c^ι.eSWΔ !.":|%kI!'N^756d*!xBٍ>ISiޓw$u5% zPr16#uo*Ȳח2 7ٓ(q錥%SA oiC :bה92RGù%KoIA}ETNR6I ]Z kOq!±q^D-0Zt^֠ DF=T2quI?%2F>.\-ght6}4:sa8.+UOX %%IW8 #ZL#~BN6Ӑ[KH%<B!2Q׻VE()a&ULFG m<RORJLC&_:~=/f#$sq)6]L~*)^;GeRҾkNN=gE"2q7?&rm@yM$֢7#E `xz45* Lg^WG" Wou NqO.Z뾫6Fнzrą3X A mنiMy0f;Q[YУL[mʛJø"F΂?dvh.HımbҜd$\RNI#bh J jȭo1ӭI]& <3)/8@Or7^u/~l:r-2MР"O7n!)(ZG [;\ MŴxe%ŠY]͹m-`zr s;s_ Rym AAuv?3 ~lc"\HRZJ_pMFvd_2{V/d_&%Y%Im6A9$(vm4!Km (jANyYC*^/{G\2ۗ霩|P IJ ~Z //Izd7hrvf˒dmа()Oi쳥9M+̼r}UA%Ķ]I*X>o#ekJJx?6Pkcӛ\쒃-2䦥Ba>RY)6Opolz$Hp)v;AR=( M{H@$zb0ċ9*˟8 R)W$!@>E @A2#ZX!: \VhfhmЏ`*~1JTP E`g_/8px@\EL {JN9 kfnp_t\PT%:8w|JUtv6= .g[ucwU~:fŤ,qd66>DXxGC;=H0v5!,ť~_'҂˔J}/LfjɄHu{Lr5/M-/vɋ#\T\v\f0W#M~C~ }Fkv[pc\c8vܷ>4pAI I 꽘q؛)wN>኉giφ>6 'yRIؖ2P8ǑŰ,RP.JRJRJRJRJRJRJRUQ WV WFW5]O?Q~fs/$V39joQgZ?̟VuV=?ugUĔ+B^e.D7cdt~s#?4PQ)[)yȫVsx$ 7:-bʖyrܧR&8p cIUζdد|\; .֯{OA*I=Onu$\[Dɑ-:JJrҐy'Us}g"/12Z Q +T qmJe"R}OFݻLgb:6 fE23=2eq)SM\J KMhW0B+,w~츌F>jDMdHhgZfDSI#]CMVR4|S4Xz e]w;<Ƌ7?.eR$oO2}mާۼ.p! ZR: ^|X9wQq. DZˏ6D'_}miqQ*RO&1Ν\+]4#% yXK 1!8y u!R+,^]#RdXU![ۉRuJZvq;~=ql$a_~]b_M TC* tlY7/6dڂꭎN@Jxk}=ۿp!3 ͅf\5fi1N|Ryp+Ǻϒ\N1pR[ #L}*A)Ji ߪ\ S s+:j78ɗuKf:PRtuHUO2lb#B:Syv}JI hXNF9ԫJdbnx6UmJiHے]YÂv7@kֽ02nęwzKn/>k) C;l׶Yvȼ7+GǯJ\× *X[ 6pv*?hWMG)ÅnWaiаVINؔ$HglbȈemqi (oD|g][=hqRK V5۬ tz? Dm! OyzƱN/-՝ S|KLʔim{ 'dvF3lx݆C4S/Ls5mܦ)VSis_)s֫k9-|ɠj97eD6PP|7Ȏ6lm{7[D;`acJ ZBϣ]1+< 28 lEgz^lyqb= h{{j=]mp.,m̾ԛDTӮ%m A$CAocG!c\;bGnhjC.IeP!;pאoK\BK#+P+W${ZVj0wI&L{oC}>[oa@F-tolpq`OqmHfS 0$?"BCKHx $[9p6Fyܕ0RIP< 㺓][`˕Đ|):p*[JUxGJ|l.v?:2WןW]BƩP0uW'?x!px[m@l!{H@$I;º{fWݙ=2@Y䔨xI_dU{e']KrH1EYJgSNq IQ䐤$+N 64h-ݝ-8OuB^(OO {C Fq ,ے.6kԔ8L)P@6FuspKz+"q%$X(G$;r }yDXllH3"Gy\#6R\{<9qY{G:k yyNٹa) 9߈J$U t89 dXWtHapqZ:IRZ",fqsƮK֯8VfTDvšW ){pz˕ZolXl-c4vJ4Es[Y$=ݳW'۵hz+R:2a(-^]AOrʈt[/[>87 ̩O=-؊9/;0IXW$n]oʴG!9e*l*, {+w - w Xz;0ix/J <[l(Z2>7"14%)W+-Ӝ~0dP! TZ+!Z! #,ۓ z̽p$iMj%8 {W]3\;{/ -1J#ۡ6T޼T!jWtȽHLx}B_uԷRܵ(Q}izCzHK1~mƗ#jCK*Zd5oeI$VМu?0nspqڝ*%Q q1 q)$ dL$IݔSWY%n8o pX5oa & ?쐕$-YfC TT%4[H[ jGKhBCIlV}v|#`:?( R R R R R R R R R kj7}6k3%F`tTS~~:d߳O:>$)Z(((((((y>kfN=̆O<$4ӪCnS:ߙaV+u>wgTMA4H $^gÜch;L8ķ m'oiRUvB~\&iWzXvlr*dG*u)Il%aEE%;I=AmL7F℀6NЮu3 KŖl]#5$%` $*PbS]}rlڙ@JBAR )IZ>vqN4AJq[VGs͌3qM6BPVA JP;+"Ⱥls?Az=*sxI* :-pTzӂ{wIedDBjɋz- S)y+JSڽBڢ]lMHf{rn%G@O)  N~s\|0,88[6dȒ"4%㾅v}#&tީ Kժ31 RgNuc1l )jS((\6QiO˰ǩSb:x1uq$Hy6PG)ph,U[u*& vǕK،_eₜR&O߭!V~ ijv+p.-Զ *K%Brr(.zTϮLr`9;>gj3w +CuԬr4;:s$!Ӭe<:$%J.bPUFՇ|+<ɉ:3tOKH@2-6w+ZTRSn\Yy} Hyb[)+)mt^=RRlkRMGPlWc&:%.\)qHҘWF\) b^+Oj9!IOf^_+JHUOHX̾iuT2$<:.ij 0Bzg]_g/kV/93n&^LdH+o[ZOs&إRVRٟma2i.%MUȫW ;hX,˹f4^y/t6/8r4&ʥR8/Wrym~=NsmGҗ`)W/l gWjeZ}bBqiwR[0B8 PZI)PJq^_7ܚƠLv^n"-[P}m}!R> Zd[n`8L1Leێ\BJ%*P*I{oЅ_8d=׭AoCnՎBsfeғnD*GAu*N|U=B]ÝvUC)|dXۋ>J'`HI?!;TRl7q;R%u˞Vkm!HZT؁xK;n] @*EӃ uE•ȐvR=5rܝ6(n/+'|@10 H RRJ@*NI$n% oMԘH*sFyKh{auTDx;C $W>)gkCCH䒔æ[ڶ6qad_S@J8'A#$ ϶u z-R/odGRn1׊#5Thқ ʎ q@G=SԬɦC†byK\sJ :a_]:">t56ÌEmuh*q ZǺu'E $.}iUrfաˆCjib!4%BP)eeJ D^Dj/ U F_t[BZmgW!U`.;}=͐ʣ }טe*ZJHxjU#a{caISC(^ )N! XWp7$nw*)}`{[,ձ%؅hʥU7nǜ1v7[-F-9pW'k^n=El p50b|*C8xJR*5W}cR`q;L/6Wɥ- |K@)@)@)@)@)@)@aV39To_ EL57߳O:~:dJRJRJRJRJRJRJRJR1\jYWݐJ(i1/䡀tK I$hS7PRXY%ȯz\;$(%!EB:ӵ$zV/܏.uz.9mxJXa3$66nwN҃Y7ʭqx/+P]ָ6h,8yzVҲ< TJv5H!tTkųW**|[&^uǗg$ڔ NPRA5{ A6-}6ANۡt{*Do̽j^N“B'A@!q-CޤyLna;dW$rn1}89KJRI\=}lYSdD4 (Z#ݴct|Czϩ19=E[<ۂYRZB@@k'1RW(6[mjZȔO+'Bǧ!k49&v3Xmm)w2tb)Zߧ6عBww[v|v,y"2I}^ԐRH ڻU_R#DZD9m]V/C.rsLTW=@dC]t~FgxV@6M=z<Ї!YSXeh;hozַB cPkIm`*~ɉ&qXqmF]>ʋ:xbbZJPJAYPqkOpmEL!iQ%[׈V@$zzPV[2 0od)it[1XHe6ӊSj Wew5Tonbp&5k2Ʈɩ,^ҞV ;JPU=@/5ȧ4nd.L,{(Z֛w+'\oK,ȽϛbҒ܌d^ĂR޴vHe (uD%!)=(5g%r,& )xKaS  aL 67}bj3 }o?Q֝*n+i5:u_J:'Vܥ!#IwaBAH!^h5ϋyoPY C-;b^ m~,ŗ4֒ hG+Y씶w܁^L#kα"L?sȞ"6/*"nT 桰Ov 1)mA(${BeKɮyVFAsMSd,0LK.p)ggC堫uh5fuܥxVM*$ *V$)E"Sa-߭qfs 2\wR\:k df[I2~-%IG!M]6x:lLO gN-)qq ڬO1WiF92-T8p)4s+:P&&A4[./q*x9|;#zޘrkAq↻cQ ^Dͷ7O,toDt<@[iTB VRIQze5u\ž #7 ۢ-~7xm:};CG Ak>Cpa.$5n|R#xz}inW9׸f0鐶 sJEE '[j67mT8@ KS2#[} TOȄ+wmBՄ>g@|EB&$I<@I`u'%u{PK=eड)'IԞ;ϨUܾᵰXYď}Fо$wΙg!2ϙExUL_' l6#+ $)ϢH8eM |N8˒A; W%v˅ӧ9[v؊ĿnR8r$KGpuهT'XV66U-R^@ N[i )߾JUY\Ir9E>eJ vGoMou/m&ܢO -<3!P]ZAqZl/K̲nbmqP rB[%Jۀo=&Эb?{6fL9 jS{Zd)GX?JTK{Uhi) ==RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRU}oC_ՃUQ WS鰏o_ EI*7կwo֏'՝UO?}Fh2}Yq%)JХ)@)@)@)@)@=/\n5H* nHHRH$'(168sn%o5Z %)t>j _%aLEBd>-9(v=6;*o&-0Es<|n >R+r°ۓzXf:.Eʒw_:°Op)-@W󞍶Υ~P^1ȦQn n*#\mRR lxɶcotECk i }z@iXī:øR J$G&[J( /iQNJU(ۺduͲJJyˉ*;u"Au'D!hu[B)P"ťF$Y-tU>`i,:G=AO/zocÓ%6q%^(Z )$`U]6VM"S&YǑvfdF~ciR56@ A_4G.SN|JPV +V0'^1;sV'}ɥqRPR괔 ۳kJvI1nJPK&|kBTT@v7A)VoW,Lɍvel]]ñPZ@J|-!G}־]W[A6p]CX PvEDrJaZ,ɘ3.GDtx`KD$ jJjt%1"48|XPz(+kw-6l"\Fq%HeAx#IPz٘@g]q[1"|Qĩ% ,+ kgZ=Tk‘|?*+lޥ\}uvm yk]M׷+ -לJ-$[-I !>V$ u߾{Jݯſb@LuzpZ $Ʉ;ʉ+e](V33!Y81 +H zoAhR2cj,K{3Q% .+!zxB7W,DMLSu瓘 zO4l+D ]HYT/v/k"55u,Re¥JHm`%*'Z=a!Dܯ@C7[m6`dŋobQ.:\>[XIB܂|Ds[&r"̔8`J(䷥6R)$!j )KRGtAgҫ +3V6{Me/o+ ] ip >^oϙ ד*]s!B\Ju,6$$sAiҪ˗YZ, ۰$'ZRb? %/+lӭwd}Bؠ6\{?HC[u4JH ,((% <{$ďl}$\(Rۃ`짫1-S-Vnؙ̲ %k)aiEfKmK qc~J Aɭr,1qs~$ z=y!pt+dI[;Ak]xpa_w˷[eLHY$l od|_f`8{8䆮 GdiDZnK ;IC`$|{ &T]d+ze?ҒM9m1])Ջ xZs&멒SLv88}Vp/*%x󙽘XV?re#JnE`k|=Fc+\+;kF[3* (J*6'adݎM UK~` _(%J:CiPLXwSgˍJK'D(ڙJm^lТ{]v[૭>$ɌO$ l㷭vʶ[e[no$wJ(H׺@# |m9CV(5sFC·"SV݋3̱%hJ\SfJig,1u%ODT5!Ĺ!=q>*x;|uov UƓŵ̆@W|( x"2޵È]AdO0Ut/,ɄJP=BTIG{*yx$-oҙv"Dǔ$)N\u)JA:]#.4U쩠Pқ R=IH#^s'~zi^ߌWc<lM,ensY>]i>*ԒI)-3'N_e rWLǤ\cۭR\xJ AuT'@s-ٰ e$j)&;mtv sQ.̽ D%*q$id;ƒU]c]Lou݁T*lg8 ZPkIF's;M@Oxufݴ-\||IZKK'N<4H5{ϱY'DixXC ݎ%-+AHjvluof򖦒K',H{{&U_Pla{Py 2츲9(fYv[76=^Td5⺯qOsAE'[x|;69d-̸QL%YZƔ|oN`i|ATN7[{xs(eLlDqmC-)IRIJ$o{:e= |ZCFBJ BN:6 dS+#l7y R{O,NU+m)/ojʼ^k1_mbs1P 2pK}t(v?fMPH@|0r: ^7g6DE ^B8R6)O+*oN=ج\d <ҽs >)޽t>j g=FSnLsr&d&JK\)BPI:; 7<ڔʃ+ y{P#=r<\J{ܪJ\XTveN%h  ߮ֈʏlS 84ڸBHx#`5λ_.9L7Ļ.d\YNIrC+m2)Ũ$o->Ĩf4%7.dud.ɉEb%[m)┟_m$ 6nv*kqdv]YlK-L$Jm HuqVvI J DfgaeoTve AlIQzc dV ͦ tYlY!IwHqj+/JtDմ]P ÐV_XO2J'Z<$} /ȷ+k~p)MZO}ւ+6|r1msHv+ HkJ?#Fѭ3;nIPeR؇Dh6Ya\iBGu({JE?ǧݢ]Xr0TYoDB`B?5f6gHV[%(K%- >[:ߦϚ˲k>?*eh7z7GΫ)JV)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)J)JWFW5]X5\YezlO7Q~fs/9!?Ln2yOK&Ii*uE@w%޻nZto֏'՝U.X#0w\tIRIK$Dq$}~?Uҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MiPm_c~kW߾3ҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MiPm_c~kW߾3ҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MiPm_c~kW߾3ҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MiPm_c~kW߾3ҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MiPm_c~kW߾3ҡ^ZL֯1|gi)5B~?Om_c~PRkJ{mj3ZL֕ f7m=~?MAI*o{mj3ZT+kW߾3f7m5&W֯1|gioj MjF7ZL-l`Qa ִٗ. A!cХCS}W_dZ,7raQ1˭T\I#'Qξ!M[ONS)dJ ^Sa%}eg@DG1dތ6ۊih4dR@۽cVYWuuuJ gL1vm]c.2u!\~kQsW6"|iAeG<m~F btl\RԛրyٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3olj{MT?ZNϝ[hj 6oSx5k=oƭyD[hif}-57fU7VӢsf}-4>{MT?ZOi_i9>yٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3olj{MT?ZNϝ[hj 6oSx5k=oƭyD[hif}-57fU7VӢsf}-4>{MT?ZOi_i9>yٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3olj{MT?ZNϝ[hj 6oSx5k=oƭyD[hif}-57fU7VӢsf}-4>{MT?ZOi_i9>yٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3olj{MT?ZNϝ[hj 6oSx5k=oƭyD[hif}-57fU7VӢsf}-4>{MT?ZOi_i9>yٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3olj{MT?ZNϝ[hj 6oSx5k=oƭyD[hif}-57fU7VӢsf}-4>{MT?ZOi_i9>yٟK AoƭyٿMկ4ٟK <ϥfU7VljtN|ϥvgCPoi_i6oSx5k:'>vgCO;3o7ٿMկ47;3oGJeUOKӔ4@0 6oSx5kbqf!Mj2.LV[dPP;O L:eXٟv=s~"jaꐅ?ѧ{qyŸwu-k;RK$}Mx-7܆EL.JüZLj*Z|rIJw;> 7O}yT^!Ԥo'J:ߙLKIA?dƧOWtQ)J4)@)@)@)@)@)@)@)@.e[k8\]il-*=( N5X,"c0x^"]C8R A5Ou[\L$ᰦar+V\HS@R&ظ(\[XTeV+I@=,ߓûyBTl'G$[վݫ1'ڵlhGɖ:.C@Zҥxe$t oJը۾Ck6׌<IOVTGFO@O'~rѲ!o]\.#H4B4[ ^q6vAr܅8VKm֧[!I o[<Ȋ>&4Ap[eL[2maW$(i@$hZۥ{TheO½D lw侠M!.n7y)pJ+(q(8 P>!ϲƒ. sڜI攴!r-BT:G -]njC6lac0^} hȿ(FZ%Iq33!"$n$2@RgQ!!E6CmXl.ȺoMK9BIaҶI=S*4)X((((((((((((((1c¶Of"Q*$jJ4=T6M`mԈg "'(mA[߯#;ak]ôޛ$*Te8[UzXg0ˑBcQڟ Pg PAH AZ3{[4$c.]VbYͮ6ܫR *Z#*?Qw5.Nk[>*Vz+\Q9>lqZ. 5jRo@|mOa=l9;(Х)m:S .o.x{;MH$#%7(;shқȄu5ǂw)J)J)J)J)J)J ٥|V$č`e1.6ɓ.rL~AHYNql c^u\9 ,VEZ:FCƯ1xC[+)&ү6rBh]v e;y |q\?'c ~ei8CܗR IKԕ\$]{*瀰ͽr` wmQ Ag-73Z)J)@)@)@6IcN: %l{F}OQcnFٴf!|O^'-pzAd1/ 5sf5CMihtO[]@)@?_2S)~4y7Q_RRBA;>ToQӯv+-{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݩQӯv)e:aj{CtGݩJYG=G'Nd}ڞ:ajRQQӯv=G'Nd}ڔ{CtGݫ +YNvGOc7rb/$F7}|ԥ,apvlv-0.1.1-Source/ScreenShots/apvlv-0.0.6-9-dirview.jpg100644 1750 1750 133437 11521211167 21574 0ustar00pengdapengdaJFIFHHC  !"$"$CX "U !1T"QU#3A245astwq$B7Ru&r%6bV1"! ?HjSpGmܒI;5nxQΘYJPKbL.|tO k@I$&Oy8;{omKoox=5~ŚyY)Ԛݼׂ7I,ѹs;$۞.hW>[h[2j;|nJ<\:&B\mOY4bgEϕeݭqvw "c$4L ]ɇOa9 ӆ@hܥ-RŌ^r|[*!la kp6}C')eK;^[l a1$|op- ;nA-R|S'K%e9kS5Qmvo` !rlMԘbعR-5,\ AxcG 7sZAwdп-R|S'Km'ESc27FVQIiq8o I Ww'wTYa!YaJ9<5AKNaQܨ\-R|S'J5&ȱ;UM_ǰғvj [z.[3ɛbѿn&9w5mH-P5&zc6+zh'sUQ1wjV3"̍I;csܒ'3T,~ܐGvF=ˋ\M~|Yۻbj>[͑WH9~GJzVbh#bpw4qVg(̖l9s^l t JE O'o5?ԹKgm),ݲ u%sd3>o>MgnuT{-Zw|Yڎ:FlS p` oT:G?OjW9 A6)͐ZP%$Mtc䘈i v5ZSˊbX53d 9Ogq$ ^_-Rol*͸ #]G-d6xcn;w(~nNmel׿Z7kbgf_2orN}kvSSDPgXZF^&<݊م)hZ)mi֬ @WZWh2S>9-Pm23hI(7Lr/t3UxcN# :#1ӗ[A1v;Դ#*_}Y#,i-{IW.[ neX_{?  j:iDR|qRp=𸹭Umyv{cV"exlNIU.CYUةH=NOWa9-MOP;K;%gK#j Zwg>i'u@c% ItU7׀=[K#ðةH=NOArZv&=;ē92847ng}KО17N29<5קsNok\=لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=NOArZ%خxINsOʖ*~fS{0v+fS\2لT$'%]焟ٔW<$̩ob a;?  hb'e; ?*[ةH=QMqBJ sXk5b7“?=焟ٕ]Bךjԭyq1w=<$@Id_ ] ݶUO7ԸjoR\XlK/m;mdrpJ@Y @Y֐ΝItuӵZ89k_;.__~yc\kFY@$vߗpQFGNdHϿ^͑eז86ɧlyX c$|΍śq`E骇vE/qYP&퍼|ݶ<,l DXUbGHLm͎o-NKxf4g5}>16:{1j}wI(eL}6-[KLf_eBGA{KjU8gk۸;8n7pQr܌ZlXz^[ tqcC)/m-FddjWj 4-^К; Z:QGdk^Z\<ֿ~.3Jf3Z\br%Iu%M't6j2^'1^pTq7q̷s [Ts5rڠ-Y=LbLv!ۅa|L˝wUt[pBblr斿 ٤+#}ŎkJHdvyls=mosqsy """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""n +^f+ORi@clqր $)X)}O '\2zO۝=I1=-3_9~Ne/edڥw2yO~tWmRU3Ϟkt{-kHi6F?\+==h3{?޽2t2CZ[$,$n9cU]<&C$t5soa߰!q Yd]5ΐru ;q3ؽ7K;. WJ'KgG]#?dtzΟ}Yے7/0Il;XeXsL~E] |Fd357mvW$CCTkv'ig.jȾicӍA;DCi gCKiXi8okQ{ǷuDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDRDu,w'ŇRZy%u*W+P/2{twd,wd,HrN~?Tf:HIK[5ϗ/?j.5#,p` ;o˸(#tarNq$|߯fȎ2kgdgF80?SkM9L J`} n34e'coazjQ͹ro HڎgN2 ,36&]/yx`RN*k7,i2.TRK[Wc"<YJ:orW(-Z ֺ0́eDײY2ufOh$DH{]b^A& ,kmSC#$s1rs@,+sO6$<4]d>X:k$|ݜFtNrX3^MUI@ߕ,?5yA3 [ ]Q>}9 k/;=f/0roχſ5jUWIvB6*H̎glWXzyZwqdmt7c6*9Nw]-\-ou|pgc T;eUYv]ik˜S-fЖz 2H `! mDXoeԮ]ZkAsY.-7đ6]L5x[/M2A6<2V;wLAbH# %ܐ6R#pUuZBiRs/2"?W,cÇ+()Xk`M,Mc].0WFޮglp%c9Y|DA&xFsR+I[%5W,^`17mTݣ%gq"z{C #I; 4o8տ}&bua:9gYR)+n{\ ~lnv[H<ՎqػyE}giER~qQI]np8 ΅'q2~jv_aGOaۗ;GɜAԍ2Gnkߪ3^H%%qn ;RY uȇ[ӶMH^mݞF;ku̿+Nlg&::SpbBփc:$+7^߯%k1q7zRmK%0xZMfdU^ɤ,,,1gS %,q tmYw>5bf4 vYd0oZ&:2^Dv'AP=Kst 4>T<ۄ*aV?X.܊%tjBuR]piiNܨzS]/[!8A20D;$Ѿ&7C4閖gJ/ |9zg1S|Vz/<81۽_ZS.M9^7aoXJֻ#Y3$Z<^m{ƦRxN:83=ㅵJAT&".HkAG-W:;c+cE-,l0:s dIU-"ӼGoj 5Y<]\V3kug03 sxK%'sr$AVez CǨfmfbaƊuO1퓍a!!]Zޮv̀d3xb&b,bz9`cdHyqw] O8njfvaczk s#=&`h\Zeägodi2\GY}7P$%p棩ME`@+ը8FVnu`׮m.o[WZ :]{Ij)F*8_=ˏp'X"ȹz >֖gɚxLM+f%vp7c`oX3noi'A@~jw3WC#[bJ s>|ڤ;uO<.eLeJ]29_{K//y8ONim(V-͍A{>fÕļ@[[21#K`#@ HTdauz-pC}펴&IR-D3# \p 8AFK冐!RT}RRAUrW3ayvr@@M1Yur5 ̾qW傩x>)\.lh1 V[BlddAE\ڇpi vA'N۬k`,dn"s&1> ppw'~Rdsffz*ƥ b=\lI9۹{ KG ؈(:VZm-Yd/ ; Sd!dO FY.7XuePGhGF"ܓq*D~ԙxLZ|1G=߫ߜۭwugF80?tas:%QPY;b/4n?i xf"e,梂e1{yL@m5kɑ"@jͼ}9b;ڰGm ]'< 8l@ -DTZ]s]=O,|Qpݛڞz<TL5VNH9[a%qGs'vF8yA' K$ }\sLwdهME.,2 ]45%qaLZ1QC51e)9dt1Ewk>B8 ƽcp;=!}UEv2cSQjixS* P9lLxvz( Nة5C} K:u6]y?a.hxapp$ A8!͍bnY{%7Tk;- p1;@e)c9Z8"h9;o \nZ*Rk /f64v i)2 v= $H$+v\ޣ5wɷWc-ɉ1509{j/@$N?#~L;#Ηo'쭧dY"m0n\/LvӚe\ŎͩoZcEVxke; /8%T[q.Y<̥PCgGC 9g(梛XX*چFQ=LKN$F:[ 8n9쨬oS,۶r7ܯhuLkOlF08EW]RJv.vh4 .6]$0pǻ˃^X8~`ER+V[K,cl_+$Zww"G'(KTm>Z۹a;=Aw\<o r CWƹ. p%g{ȏA=adMڵTa_#e ٸ%g>+(:R%\Y٠#n~az AB@ 'aU% 5,zVCfI cxDVgJAr&T,ޣ&# &ALƷswV"ߟv3/= F8N?fBuش~#yC٪xA{": 9V͹u>4 [ZM:vp} Du,w.Qqe/1IaTV^e~I]JJ?̯.!]=C?:C?:9@80 pёӺY0'q8>kݟVt_L`2m,8vV5kpxXįtΞJ9ԌZ[M3#-س;yr[tALiߋtXѷ1myvsdfG+J)$d|pI#qvčf52i2MX0a +c(p xlyȈ #?Yc)rX)}O(?ҵ+JTV^e~Iq @Y @Y֐ΝItuӵZ89k_;.__~yc\kFY@$vߗpQFGNdHϿ^͑eז86ɧlyX c$|΍śq`E骇vE/qYP&퍼|ݶ<,l DXUbGHLm͎o-NKxf4g5}>16:{1j}wI(eL}]Xds]泹2ٟ$1D#N-ccc|<; QQCj%~Z3/~T.]GWu}nˉxzB!xKuZq Wؤ/39vzST:-eQj^/ke1;C{%xc3 !r(F.(kn=gZ}IqBܼv-aA +yOne?UC9ڳ 媷KhWnZ޷] .{7`8pQI_-f $I0ѵZhoI =폃=S0o&qR7P~zi"G cŻZH.ANP3a?&>?36x8 dB"(N(Nֹ;[,EwpW2_3wgq+Yj $2Xݸ {v;lwA_ul}#􇘚֬Ue㋰T1kA9os`" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""X)}\:;_zbĩ_C+A_\B52UeׅehvV=C짽^ޒ?Уȍ?5.߯N=Ak瑱ܛNNLGZkܢ:hl5&g]RGN7MjX 1 |}~V;^Za=XYڷosCܓ?X>Q_e=OtZ6Yde7|L߻{FAE-gN8n NÐH8y<>{ܟP)r|T78\^"gnm@3n3{7 ߉=2-AQeyr|W('M"u6#+1w[m ;9K.kpc ő /`tsp ỹyS=CܧO('ztRI}$6Ź [Y[:Q͕ KVw2~CA?ݽo=C짽O('o3l^{Uijp^{6yG}}>)SZ(zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{Q_e=Oբ zO{ZR^bԃ1UH^:N۟,_Ъ%J?̯+RZy$%#Oޏ <.<.ْżM >Y87 /#+[[O)N N].,rq$u XWpzzgM-챍 j=mqՎG%R ZSx(b݈Йf6p<<A+p;Ӷ_f':}ǹ/o{8t6oܖC%x],+mqsNI]/#/Ӻuw`@zMH r[rX6gzw#>l|pGww>g?tO{8ty;w,Vݒ?r[gI|ҸI\O2Wڵ-4t;`7q;޺'=_G_ӥC#m拣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz䋣|ޡsOz,_Ы[=_GQUJ hԯV3v!1 _!aTV^e~I]JJ?̯) @Y @Y֐ΝItuӵZ89k_;.__~yc\kFY@$vߗpQFGNdHϿ^͑eז86ɧlyX c$|΍śq`E骇vE/qYP&퍼|ݶ<,l DXUbGHLm͎o-NKxf4g5}>16:{1j}wI(eL}s_ͤ4(3.twYfFbB=G2IWAEx-6_0h`sZ:-eִ[ű-;˸}9,1'$E7KGT2 ?HV(=[s@=ܗ2 Y U mAqlN̊1yHse[]w>;tyS2\I "198O oU8#R#6aɠ" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""X)}\:;_zbĩ_C+A_\Bz;{u;{u9a?fx ے@괏d"ʜ`w>llkyƪ3RfuE$tc{$֥-s˗yN"'9Yzr1]g f1ރ~%lyX c$|΍śq`EoO+YX2f8ipo\{;pCsCi nG.fR(9n*M7f |-,K^c[Ÿy߽ܳ>߽ܳ!Ýiqldc ~]G ; w#)]5gMA ܒU~c%1T;jHazjQ͹r'dhW[L ᑻlf+w&9zs*5Xj~.6\D5ۑ=/ؽ=itbzX8\Ap.sзH9к;PXțv7Ed[vIܓh)=}I)k]̅49r'uDH4Nzu"{ ゜qP;84 .XZR &ptr|͉l=awj2gOob) `捆wq~M-5-#Úw~[}Bߢ&_K-UruвZ"ݤVKOcNmph #?Yc)rX)}O(?ҵ+JTV^e~Iq @Y @Y֐ΝItuӵZ89k_;.__~yc\kFY@$vߗpQFGNdHϿ^͑eז86ɧlyX c$|΍śq`E馦:֛r22 78#fisA>OcmQ*X=9scg)}S1vұC>E}6> G+8v38okoYzrլ1M->fՊ.638|NswhTSz7Ygk[}laN&i6HkcA^eL1g aY:ή\E3h}jN46>} TX̕&G1 αJ c p gu~G3}4dbdx&>'H2"CjGK@= )fK y[R]h*.'Ms6%rI?[xhڏ/)hZ⍐ѿ3X,l@! w.ƈ(|I[u'tر kT,n#]%;nv9J+h~lݢB]G%2}~045@ܻS[SڗRn[TŦ!|lpՄe&{: 䌂Z3if..'Y|OKTXֱ+LBNq=\]̛qso9ո n&檞ɍ=N*O_bp148qsnbMWJk'ڄۀmm\(Qbpٺk( R2ޚKkVz=vq(|ܷ`ljiq+kxe0F+m13p7%VwW2P'sExc]ݹ.z s_kK3dk<&&3mg817h77yGQ.tl69`9m h4 [y 'YkMln 2jVg諝\v ˴u~{Njʔ㡏b-j[0GZ y"b鎙u]-Mr۹RmFI#1LIK->}c3N ][X8]~t*DkC$0ֲ_α@7gnn@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDRDu,w'ŇRZy%u*W+P/2{twd,wd,Hrv~Yp@}$?iLE8}N~?Tf:HIK[5ϗ/?j4DNsMz5bca{ mri[V)3qfsxyyW [t'C/$Ӓi[) c V01( kal  =:w؃ѹ yh36/DhUر2G0=Zpq`[};oIr[Zh"UwM"JL%{x{G tJ5kn#ҹ]4dR*|x1)^K HC,sa_Ŗf/%ٜqX`nX`㄃c#89!}$?,N$(>Gil_&6@ZސY :1&2s[411ݣ>bPxb/;p:A1щpCcmv7mg .+NZz527lG^pJy/589 [jf'9',J*Y&g5-,π`J.f׺'Ktn QXF_ q60N #[=b[H!&5'/Fax% kd 4[\ #?Yc)rX)}O(?ҵ+JTV^e~Iq @Y @Y֐4׶H.ࣆɅ;đ_ nI?S1*q5$|0TEV(ttf @yi{q7q?jr1]g f1ރ~ Q v@i%C  @z~ e&QW,|umFA~ߵOy<kp.5MzCKFŏ;ncyCLej8ZKk<' ŹNoq$5yD'Fpɉ4w,VY,BA,-; Him?jŬ&cY-zcmr-B vKdi߿M,Rwr;}øw$$nv[к;PXțv7Ed[vIܓ cIp뾼s#|l5<8y=0ۆLM)dڲb f 7qo=9_ \ PGhh=B+ fcۈ{-UZFQqu1ۮaA1xݮ;b?% rZi3Uk0Xx~JtVl1,Helѻ#F5w;B/,@F;"׵q}P}DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDRDu,w'ŇRZy%u*W+P/2{twd,wd,HrN~?Tf:HIK[5ϗ/?j.5#,p` ;o˸(#tarNq$|߯fȎ2kgdgF80?tas:%QPY;b/4n?i qazjQ͹ro liJ# 4Ze4X^ƃ{I^5>"oYem35[DHlRylRl@W*9SO芳ֳ ,nEhm@ #kĮx=p?նGSjan#s̐5̆5XG+#yHrދNJf"6f3M݀91h_(;lGMtEX #a'7kw G9cW?FKJ]=\&֤'иpchq{:h`=cB8v;׶GK&lmY jF̏/~"FN Iii:T⡂kOC,uFdz['amm?m֝k^~dH X!x'g4nviw$_ZkOӯzzmey<$JCwܜ4MjӘ[{|wJR˯uW=eN 6R< I>Ӷ11plQ\U #lCfpp[qleߋ#VZq_[*fq31o=O8C~#yC٪xW%&枻Sk0cfwp<[Đwܓd,p[6<2C l=k-5,T }v06D@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDRDu,w'ŇRZy%u*W+P/2{twd,wd,Hrv~Yp@}$?iLE8}N~?Tf:HIK[5ϗ/?j4DNsMz5bca{ mri[V)3qfsxyyW [t'C/$Ӓi[) c V01( kal  =:w؃ѹ yh36/DhUر2G0=Zpq`[};oIr[Zh"UwM"JL%{x{G tJ5kn#ҹ]4dR*|x1)^K HC,sa_Ŗf/%ٜqX`nX`㄃c#89! ֗wy@ie0X69.I^(>Gil_&6@_eW@?st[V,ת&usG{2y: !T`rZ$Ӌ%'B7kC}Lˑ܎ tt:G5pXcÁsC@A$ sXmbZ!N'+)rIcywn<|k;}*u(uSdw-/#ug%q9䵡cMoй^fHx+բ=d{r׶fW>n'mnt.;H'< 4o>0渖̿bKdc״lys5= Gة$թYs++X,jbql~*FHbI*9oyqay#fn7A}1{9k-p;r*]ha-L#W]on>{ltD>0ulݦO;s:G0J:s= ܉Y˥c-sioy -\>wUt[pBblr斿 ٤+#}ŎkJHdvyls=mosqsy""" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""X)}\:;_zbĩ_C+A_\Bz;{u;{u9xs.5#,p` ;o˸(#tarNq$|+?fx ے@괏d"ʜ`w>I1L/UbU9#369y;B>8Z^ƻMoڼ܌Wxc9w8/b1C9;sIinH;7Iq붋av_qO5Di d,; Ad0ސ1c۹r^ln8c?hc8Iny{+x5O`6JhY6XY[v@Ay~ՋXM=س+Zǽ8 9wr[A`Y,^:#lRNw.,a^AI2r`OrnifHK6sG`uc1تp҂x#EL `;@ܽhQcK8XjV)cR 2"_w Fj2׉b2=fiWNѣU_3UdmG!c/7sJ\lĐozyC/cѺFs gr7gF80?9m=cos %U'Y`.;$0TEV(ttf DjfWt{U]_e}e1Bώ|d'i v9_7O& 6C!cV1x{򸻃Ǚ6*)= zU:l>J/VYF+;!nLa pwƂ諹93^:ޚČ{*Ad8[ ˁ܈*<ϬfbɑbG^O(dFks;=Xp`u@ѫɈR}\|L/=7y&'pa 5E;̋9  *AZëZsK y=asv sI%7͘u^;42֢hqȚ=kXZq" fbϘ֭[$&ZC,.>V(Zxۻ%k_."Ŋ9ԣm]YlPyUo7k z\aAՠlQA].k!xˈ!q#uVUcfC(xFf-K5"kPq$XQfl#k֫ZixNѷm;`Cg /T(X=*N}ať?w\9SۨC[k@ވ:;_zb(e2ޘ*W+P/2{JPjWt`iXn٫:n"o#3)<<=[<G1ԙwGQI;X5cxƵG^}ӆ}iV{&^܌Wxc9w8/bi[V)3qfsxyB*#-&tͱ,v1~'[5›o߲rnC7jS7ɬ]/\ =1ac b kD-o[,u! ӝM\%{OIGc/˞ƐZ?9X'f[$i99+7`u0BD^1Sˑvfl2@tV=wxsCA 1{C3#Ic;\U5D`Zl69kNDtxonzXdQN",7þkyo  ؜αP ٜfR|>wmI#7w Y7kis.RU Yۤ~(*l2H\xK} :=*pGV5bG m44Ó@e@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Qqe/1KG\~KLR|Xx+A_WR(?ҵ+KWOP~OrΰP~Orδ/v9ƽDe= @x'mw4dtL.IN$wg՝77rHVYSGѩ#6 ,UG#{s67'}[xVbX7;oA#>܌Wxc9w8/bCbc!R(VEؼ5؎"vǙwXi-NjT8+8Zw ?\?^H44fn<~1rɯVY;9ؓw~klR k4t*1Tcro[A`8_G2=la!9ѿн}*aNp"&~`=/J PRk!j\ͷqH" yF67~I """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""X)}\:;_zbĩ_C+A_\Bz;{u;{u9xslkyƪ3RfuE$tc{$֥-s˗^y@80 pёӺY0'q8>k׳dGsm53i[V)3qfsxyj:jK\Vo/bɿcoc`^"Zr:Gg3nlsylw܅che+:F6{x\X @w7#&phs= بX WSRPr1ް~@]&H(_%1 kA-;r?M=mXf{ Ź٤np$JUX (O[NFkwVɤFo#/hxap 6}A㡊ڳCNYNg ygW&2 GBuE]I7$_潁psHwD@D_C "$>8Id|{9pkZ7$Qǹp7'ndG֗8y(>/!vFrA9hsA  #?Yc)rX)}O(?ҵ+JTV^e~Iq @Y @Y֐ΝItuӵZ89k_;.__~yc\kFY@$vߗpQFGNdHϿ^͑eז86ɧlyX c$|΍śq`EoO+YX2f8ipo\{;pCsCQ*X=9scg-O9Яl)ah2A#v?SVΝ E; sU-@ɢ,>?"toTճ'R,MC$q4o9S]OƜFj([YH<3#\:w G2tv{~UO C-d@NckZ8?Of-t&J]iW$<3pyw4ܽ<&pʘMKhls.~4 s5ohO.\ʵg1X6ش;Rt{T\*FfYlU,Sd^$-/ {Ov ]x]ъO=qi~*h[9 828"!'9bxC& slnjtpd#depH7nߵa+h?^fH$8ؘi4EtSߝc$yfxXG3!#k%J9YnDjcleұ4[m ڟ; PISfzz8!k{co69@s sK_wYl.2ى ZV^#+t}n8ymւ>bt5K$t]ֻ<69K z9۸<G\~KLRR%JPjWtԩ_C>߽ܳ>߽ܳ! 5gMA ܒU~c%1T;kg;c]5Q3)#k&,qosֿw>\HϿp9ϭ5d+8Ls49Q-? c8c#tn,o?(c1[kAbiB׀]d kZ󻃶݀;xf;w\ެ]_;!;_&lz{5[pHh6BEֲx|xa|XWYe2OXx=w>3GO7o߲z8qi~^\P6D5vf<-ጓ5^$x4A#g5nQ2v8x Y25ma? գ mdnF6fs3L-c_#̏s؀|s'E;ڱ:YQV%,/6lÚ\p_W7{P􉚷_NŏIT%=N7&3w6>TӘyefL(6V6]+k3K{h-;E6jط6c048\u!Y6,wCZTGK%]kc$'kx󝻏{Du,w.Qqe/1IaTV^e~I]JJ?̯.!]=C?:C?:9@80 pёӺY0'q8>kݟVtlB'9cCZKw4=D?riL 8;IJgBh1F:~ό7y? &c֍˷= F#,.ڮoiMxc.[wJ͈:Sic CeB({-h#u2F^.m;_CI^J,܆2{Ew G w~%R3[1$ޫ^j|tno܍-;\yG\~KLRR%JPjWtԩ_C>߽ܳ>߽ܳ!Ý;c]5Q3)#k&,qosֿw>\H4׶H.ࣆɅ;đ_~"8˟i,qmONH7NS1 x -佚 *m.'u8wks;{N56cid/EyX?۬c.km& 1c,RlkbW \An[*kOSNL:`5*a-۰;woM~C/sEmUj:Gh4٭zG0J:s= ܉Y˥c-sioy ȏJ;6b[ewmXZ6n\e)s5A G͎WF1psP[Su^wA?Q 1ڊlձoOG-v/lm(ax.ikp9 B?'lXdKgF>IacOV;w9ǚ"" """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ """ ""X)}\:;_zbĩ_C+A_\Bz;{u;{u9a?fx ے@괏d"ʜ`w>llkyƪ3RfuE$tc{$֥-s˗yN"'9Yzr1]g f1ރ~%lyX c$|΍śq`EW)tK1nv7^h ~:E@hK6^į;0 E[,^sNŅh;wS+IV18{cUOt&,q8&<E9ihs.;7s{s:gfX3]F<ڀ3@G2׉\hz=m|G1n=% k hkkbWFG^) n!scQ9־Qv:l花GqOZ#n@9rǠ6~&znM-yIapA-^-9^y?b&5۹-@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Qqe/1KG\~KLR|Xx+A_WR(?ҵ+KWOP~OrΰP~Orδ/v9ƽDe= @x'mw4dtL.IN$wg՝77rHVYSGѩ#6 ,UG#{s67'}R%bca{D@^ztS6 h1n@YA4pa]I;k#r\%ry3z]RWUqruxUTe6pv;wA>vzxzqI>k3߼yYdOVlu!#߻O#On[s|.hpapv y~>`N  ִ},`BC4TE: _ֳBN>oױc ~ۭ:*Ȑ CNhIrt֟^ >xI9̕<8x$qoeDjWNէ_R:5lrOYwwaߨfW̶Ż?W7;D|m*uluJ"os֏}R{lCY%G ?=gD|}*!|4d1i's[d{%q?ѩZ~V&߰9KI?Y%gDKWc[`٨": RD];2YqoDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@DDD@Qqe/1KG\~KLR|Xx+A_WR(?ҵ+KWOP~OrΰP~Orδ/tw#FjLλodԱżAcZAr#;^"2 <2:wK&$'G^}l.-~M? c8c#tn,o?(g9O/`)(RKh$Klhho.Gx3l DXUbGHLm͎o-NV)Unc:˚ZHH[75k^ 6&b xif>Gp={O էrZ(ϳex"\Fȥ,tq=.߉#Hѧh٩fpCiyh<[hbƺ᪙.jYI~,|vEZ tUcCpT=)ͫ袵;ÔM`vFJxk7a!{|e2enAkmEM а7pry[MTb<2[%xVdM @e߫-[tvo>\}Vb[1sڲEymXɢQðz,+NcL{fWc n#[5=Yq];Tu7yo.㹔~Nl6`8lV6lm mhjNx79eےv1ze:H>':.34%@[ /CCC!\=ۏ_RY0k{gcY/uzxghIժ:b@٧ ^6xuZٛp5[[PwAnt!ug>Q JcG\cn֪e.Wb޴9ff6m,s9 Q (ЯjqpFƆv %zAzU[5!o4fH;KK9w҂3}e²zPmߊQ:+Zj=Gd䯤nц:UK5wf~u[mY7LbP~OrΰP~Orδ,7g՝77rHVYSGѭtw#FjLλodԱżAcZAr#>DD>׫=X\nF+L1;{D-+dѸ9<=0 qYy恕!Gukog5nEo ӵ9.B:W ㌦k L0GFAnM:ŐXW4[rKk':z@TZHGTawC-0\ 1bg1K:f'Fװ37F]պSPi e[^V8!m`|m /sugx#cdHn{ƹsZvpB$1r01jnajZF xY,<|UC\^^6[}q֪ԥ`eczc{x\{-;l;Ab$E49 J<|XanbQhׇ7ù&z ;Tu"WX*f`lXݙ#-o88-ԋ.'>UA̮\EX29%"[vZcA2ӳK8 b"0PcGhef"Ba6 t`;w  \QNqsYils{ChWFDr8N#؜αP ٜfR|>wmI#7w Y7kꋜ3.RU Yۤ~(*l2H\xK} ZՈ16MQOћ[ SSfTńaFZɝwREk&u?q }{'gX(}{'gZC;^"2 <2:wK&$'GRjΛ$HLJb,hwԑQ*X=9scg-WR!qtb 0#nF+L1;{Qim9h/(ێi,;w A ^^&;0n4~@ DDY.g Ⱦ0fd-CmyڼZMkYnkN4`G}>ycTV(I#Ke~F2u6c{Ni-2pxZнk'4n X|{)2:vc#n0 {.ӸXXvDa!c#bǝsvhESu8pTc2y؀dcO27l6fH 7#l,m.bݿr ճNEQahls20 @a`oC nrRk!j\ͷqH" yF67~I1{摸  ҧ҂3}e0}-λgV)":aX_>߽ܳKU,pMÞyYm? r;c]5Q3)#k&,qosֿw>\Hن\k {%h$vpBӸId?V|[Mycco^b1:7o7ǟ)EfB,kK6W'vۏ0nB/UU}X=M Ei=[5m=9+קU'pID}lF[,`u `oRZc5wP:c-25W8 M`g1x˕u)̬FdkݾnImcPtU ŀue*Tm)]aNGuR𴈢qsCrκ r[\=IV<ߜw#}ֽvqV&ҳC =V! n#man37-BlqD AX_-yqpteS7q.i8o?&/l FVOa>@؃qvG 6hp+fj<gE3'A#k$aik[%z8-%8ڴjkY8DAp8bro ˠi ur:YEc0kD@(WH RNa硖u2ګ5Xtp|-$vXӧ :Ն8c4l I$ZV^cѺFs gr7<vWOzLv5l[ ]y^ Z.kCf;*Y#.tQϒXXյGsǽq榽\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3i=NO v~.hp{@:,\ ΋m;m?3e2ޘRCbwd$'A,m|\tkiۉo0+gB\~%2Њ9#@i2FqE?(+lG^!N#j#~@ʘ͝I tE??/&7l[lr;7Q>rOCV4h+ s%z44A+HI p#]`Y?,VDDQ#N-nԂ'ty31۝Ζ.VW&_ac\+Kձ߆79pDD0n1[5-:OQp/6ԃmĥN))MeM̲57;Xi9NO"cZA_J)pJ MF$gkuW3ſ |I[{?9L)שr!I .hEAefHh5dI3.DQ7Zc$M8' hCjKmܗTelfٚaȟ)i%"kI2t̏}).1O3^c@BEL&-v'VjUJ=Y(jBe74%$!N"J6MD 4i#`t=g+ Yި:&\rKq-3h&IV2OUkN+\R[J#OS\[[mIҍ.~]g#{72uFMf[ GqsM|Re::-t~MMedΨ{qc0ĥp;曆ùIFw;)ҩ[#ʒ|%OҢeFFY>*fz ?S.a'H$%!*t$)!)6iyaUg|qpCū[e7eʪٞ_USv 'kZ#a ̧RQEd`0[8:!OogRInE޾8,~PlqjkJZzd 5Ȍʹ#{f4FF+̏gJ 2'SIӵ6\S;!6;jIY'De(hW,vb.TRNiH{?(rֶ8Zje4PSnFC^)F^Q@:#ˊ[am 4i"+gmhO暑nYH{ 9k[ZZ#FП5",*l.?(rֶ8klS-`4m6vJey*J̍)_P,xIy$N굒3%C`hO暑nYH{ 9k[ZZ#FП5",*l.?(rֶ8klS-n>$93gm*7 4Gy V.Wfc&h[VR-ZmHѴ'sMHs [=㋅-Z-`ʭQt#`J9+}LI82JQy$j2+dC{?O\K*%Fm$̈s3Zr4m R-«)zc-kcVX$h[VR-ZmUSyt4%1JRV$%$MFhZ'stqIRIy*4iZ&erbdh[VR-ZmHѴ'sMHs [=㋅-Z-`ʨcXM.f-Mm~sWhśR*LDf,҈ƶ.ErdHѴ'sMHs [=㋅-Z-`hO暑nYH{ 9k[ZZk^?[s(n㑔뉋庖'mFi;"?$3)f#*KK-*CdDD&dh[VR-Zmnk2a;%5)LGco%(wJ KH[3S+CGPԫݬs}g,q̱kagjWX5峆; HͶY=c79)gO`fz_b;XE6d*Lʋhe(l4i-i늺_Tdk7HŸ/4ةMI^ҡ.#PHKY+;D̰+tҵ)(SF CjrJjhDHZLl(ymQ"K*J&SVY# 4m$Є%)"t"!O/V#7?+n?6Wmv+SFrrQ|q{urs:c)o)B5,e|G; }}MQZk-'o 1ycFl5o16 W?:p4-f@PӲ KfddM8Wͭm67I5N8cgycFl5o169)gO`fz_`5-4Φ-;#Kћ (xqDӱiQe嶑te0t5" I4ma5ayR);GW!DmJJxmI ֥!)3"5dFJrmEM2r$*nDH$lፋ<4k[Vd]+tMhY<[jbmKpѴLlOqr7ŕұ}5Ekg 6p ռ۞2iұ01SMiY=9&$Zn֋#] DN6ÄiFdm/JImDy5%\Dc=+kTVp Ig lXѭn [M+[8ma᳆6O,xhַM&4p9]fϟ+_K@hOJ6v'<4k[Vd}'cpjXAi;xlፓ5ay}MQZk-'o 1ycFl5o16GzV>lᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄlᵄVԝ@3vl*C/7ƛZRiJ3#2'rQ 􎔖K4iHwy;Z٪ϝ}=-NyOSB7#mLetL(4v&Ø,U=lRGȹr[rS;GFO)&?  qيYd+#3Uȹs3;wt>nB46D-sIRHe̓~_ȀT4kVsf34ߦ+%VBJXYә=ԢSkNEfLC-vIIIHJATFV 1TRcgsp"AOyךoM%m!_jP0@}C8@5TZfB̨_mŒjSF֞OF6JĪk0`z#)}qOStdDVZmmWKs UkHSdP5cRѤDڪ4zeFt)!+5RdڎUer,#):jg4A9JT^n+6ҕfFeNc@7mK$~u Wڹ3:Ûz$fgF#TZfB̨_mŒjSF֞OF$Z);PN]"7NunB 56R$gmt Yҵ)(SF CjrJjhDHZLls4d%Rb&|c%[&V6ԒeԊ}z)H2KvAb;\oMiҖH&qI6ZFvߩWOP^=V%t2NC$5%Yq 2KtXbcyuݴsYQ۩g|, nUЖҴ+III 2ECfI{uhZVqJԒJZF,@RVNBBhb1kmM$I,6##˭swh:ʋY#K=ܲ_cmn;VHIՏx5DZ^R P>x'MKi*SIqKRѠKI%f"R/kO}JumSE/;}YdWfQ)`Sb$#';DA.9b_^X2(y' %%qGŞjM;}6e5KSxCV,%%HʏL*p82“t9)ۑKQMњFdIg$샄:Uyess>y_WxK%!ii*p$֒%)&W"t8T\e[In9Ryt31EZ`00(ɖAtO.\H>7mKXO|ߵ.@lڧSSM§*8ͺbk7m&vIf5k?K{{[ iU|Ӽի ufʃ#_j8HapfvVB>˫ꮪuZsoTU07FwZsnH0 )ʏR\7&lsۻ|wsG"3I#>?Ɛ]$u7DHpn{"ig{V7%/'f1n.Ix;.IxnZ[U<8j d F[I6J]GȌfeYDgBA.>W"A̖TgfDdi.jW1+-;LM]#i1Ta5sc^b9J,O#nĜKy?4Ȱ ?*#\ܧUBiqj3rKWʻ]>Ex;.IxmTR#F/>Z2뤓",Z^ Ɗ\TEj:bѐk<փ<2Rn139b3 ^1ﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.Ix;.Ix@i^?K{k?K{Wᵺﶳ'ﶳ'xmn.IxGjS:J #9I/q*,3ȏy=ZopskoZwX{[ iEצ4"d^o? (Ȯ+;={5tyⵈ6\hڼu(m JG!e+*߾,:ƓɬLiVR/8⟣66~= K/.:ĺҟ%+L9߶sKK{ExTҒ򱵬C{z Fa6gIPY)p}'Lu]&Uӵ @THei&23,w%[bNF}us׽ˊyu0A!B+/>ƐgM6hR $Ң23/ܝ٬]t/3`ܝ٬ܝ٬ uRMKO"&8lh5t1u3%U RtViJ*C;={5t;={5tO]?U[9Qr;ʓ:CTVFWA*Q^l`I#>NF}sFhksJi TH(z[.DHܴ}7J{f Б%iy e/W1碴YIint}:3EW\^niHYHi BR$oyNե(RViR4$$؈k[>Dhg Eh3"Z|̹gQ=tWn f ;s87Md+;e~^c3e̵%66I(܎.D;O:3YC:3YEW\ffQî64)HI%&e%*BuE;>dn!%o8kQ&v3c{={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J={5t;={5t=\J<Տ}7;:3YFfVOӴr[BmcW#21f0>9Z>!_jP0@}C8ڃ9)gO`fz_b;XE6d*Lʋhe(l4i-i늺_Tdk7HŸ/* jur*(St[)(г[)Ci5(N-F|wI ő@j+ZB">h6$$D$3L&K2U&+g8^Z.ecnI&]HGרѥ QX΋S46Q{줣$RI$W$'{}~;H;QRSZ4t3YGd:4HҏI v$[|`^i.%] m+BĔ~s$T;>fdVo)4I,DjA!xBg*"VDJrmJLܕ-I4d15rQ2Q֏gT*:u"OQ"[q$ei'I>J#*t;]Tj( D 6gsJO#;ۭaPSdSWRWjQ+ؾWdzRD]IY7tG?Nyژ6m1қr"֠څZnbu% ؛4";NF|Cҕ_3YN mN* zd䋡y#5sH-Qћy茥%(-t$ jXTLU½UibjA$n䤧di$Ⅽ>ZDnZ%3hksS0-Ǒ%ik/)թ)S.%fIA$FV}'T4%R" J',NDDY5'!o)"Z$EXJJr2Ir@(RR FPB mL$FHR %2{-f|MQNڦăQʒS fr &֗<224TM*䬚%$(m|~~i?{XU95XJ%ЌU;30+[}8>7mK$~u Wڹ3Īk0`z#)}qOStdDVZmmWKs 6E,I KVsNHekJM)QyFdfY$J>;[4;#Sv]MZSnEE nq܅%ke(m&IŨϖ$2.D(}.Zj~ "kJ~.)Rh2"&Gs4yZWlcƒ&;δkpMV2'uh 2ECfI{uhZVqJԒJZF,@ĩ*RN">*^ޤɍZI^B)R <ƢM}O5&73<_Rg˨T5*j"r2(ַZe%#;IXd@:4.YcraEiz$wklk-Ɏ-Ղ 1 14 &YbJJ _Mͣkzj WO:R( Mi"Rer,@uԔI#2"ۙ Bд%hRTdw#/(ZCP #e`S-Va4NR)Hm$;rHCǥi9]48BiH"aa&pVJZ2mdKj#;ٴQiNuF-)QcUp52Id%J7mK$~u Wڹ3 cXE6d*Lʋhe(l4i-i늺_Tdk7dJ& 2yu:wADEey߯?F|ޔg9 nZV6E |HmNISV5-MH QIfL:dLWόqd]kdLXQUӵ+aRy4ғJT^QI;,X,fXpwm}Tvg'Ë=bc)yۤt% RR3S"2f.bcRV6FfI5u2#RO{RIuI*KmiZ${"3$=:-+yNѥjId-J#R ϖ_X9U+TDQӵj6bO$iamDZl)3zg>JS rۊFnmM*,Vn)ujtiA(t,Z^T8$p6#%xĖ[Gn9˰H%KB|KL" (ϭ+R"pclMi_٣"|B I.R oטGRBp5rS,w"Q54jJl(QNm|WġpM$19~RPS(KQ3Q(i5󚂌lɆɴݾrCj(RxĥDfImFEe3O("h};Az55&j[ęQc+))Ω&Ѫw, esME%b33ͣnt|iiM6㭒(QI o\ifARmMfev";W\K5G"CmlkJ f;}F =~t+[} !`@}C8~u "*0_eSy~@UzRaͽQK?33Uӵ+aRy4ғJT^QI; =vHW|(SVTۮÑQB:E!IFFJIDdqj3嶃I@̋x*}O&-;uwZ ݎˏ'Y$hf|Zk[I3hfۤ,ff'uI%ydg̓WTд:F%(H$/>Yb5WKDHU(Q%_-4hQr##27 i3]*4怪inQUo8gNK 'J`Zc dV Df#0q4E;}ct KRbdiQjB4/a l5>ilRo:זDiqCTiI"JiiS dFINomq+J"c(mL1RaD=KY heTu%+I茥^q?NmYiwѵ_//[5V!MB4xRSTՍKSF"B}cch%Ι*3Y/-Z2~.V#x:jg4A9JT^n+6ҕfFeNc@0Ɖ1:Q2=R]Ql6߷$,bs3L{̓V7o;Bh];FO-^28sQ73;j=&Fq)TYQd?=O|ߵ.Ac=~tHX>!_jP0@}C8@9)gO`fz_b;XE6d*Lʋhe(l4i-i늺_Tdk7HŸ/* jur*(St[)(г[)Ci5(N-F|wI ő@j+ZB">h6$$D$3L&K2U&+g8^Z.ecnI&]HGרҰJֳN܈XUVEj,QvܒڛRЕEnIs2\W'D$4%;u3LŞ11]mJZV))?Hv|5uOqN JS4iZY)KRԂB3( WUP_ :ۍJR%t"$EfNj+Jd2#":1PmI4ԣ7$5i45,I$-+N#32szvSqiwerCE|_w{@95G#MDp_b4Ӳa7 C1h']Z(?I uTȜvglr?]htzTU=YIInV++r(RUHAKS$M3Q'.f]VsieH.Sm6ԈT6RRjK2]wMFgh4b\MU}&IS D r%X,XSMŬ;YDIhh[;_b^ʥ3KU1aj[m(^5CU~DԬêi/Br>+ KnBP:#dDRّ.4\4CVB[69VJ$zrZdcNP&n̓ѩx٤̮X$eЈDDTW ,q\|'oI +\sgU$`FR/8⟎N6Ȉ;گҗ?+mYt'P:L杨')[ q֔R̲Iܔ}lv=iws:G B:v9- J24,PMJ#$Q-H0d]Ls%?)ح:RR~rZH$#BRPI2j-[-G%:IڢgBNjQRRڔ;e[tgd̺Zs$T;>fdVo)4I,DjA!x~RjY'$X!NY6+R4O ɴ|&̏$2#vYE~N&0<[M$8\LȌWIZt(9ui2a8ħɴ(FKIbX&Xq2,XH\MuTR==.Dd̏2D5: IMd륍_D rW.vƭSP& A}kf^VAr\YyKQJH+z&ȝ 85j'+fliТQ\wGc/(-.u  CMjDCj|k6=GSzZ^ʡ?gTTf.Dڃ$#u/%MGbY<(_̺̈y:J%WMZ%))m76fk[gr zjztɓK) "ǍF3v{ykrq+4:C|٭J2em1QK)VJB2<| cyGS"Ql%VPIfIdGdXqko]{w |BΡ` W?:pkU̅IQm ۅMԦ7%=qWKjZ?sXlU$`FR/8⟎N6Ȉ;گҗ?J֐ȡO<) *jƥI!j>14 LI,lXۿRIR+qe^JOv'Y]=f4KNo-HOϡY$DjHϙb1kmM$I,6##˭"@W%;d#q%b\-}?WcEiu9KJ6ddelOܺ)dwvm'"NQa*׵$E)SMӣK33(v'"QbYh=iqŒޠ$/ÄdDFdDWa!!Y7i$EC5hmziSI%ė#瓋QS5z:jAq7RIY5r#"V =~t+[} !`@}C8~u ިI?QbUِ3*-p)4Ѧ䵧*~-SG8 #ևw;C |Իd# gBn:vd$FLc?L@j+ZB">h6$$D$Qr(eCͼ/qm҃UFv#W?Q if:3QYa6lj2UDwkݡڧkJ>LL(Gu.) MS("5Aj?;V}RiG&*N*^ILL5%&qR)*:wժi*46d! c!Ce#;XYr{?ђ=; Femj]IffbbGRI|}-B֥jY 3;fKS9&bq(#0cJ32? c%>̠Wj&Yr媘(%fw%8.>_A2[V&)w\ ,So u-1@99W=1(+MOCHU:z US$nǝp-2fLxOe4|#Ca0ZcioD.W\|'oqko]$,sg |BΡ DV%TYK~:;""o<j_J_X`9)gO`fz_`:39-YW-¹Wj뚎+i*!n-MKqfYߝaܯk.ڋZdH:BVSa SmK鰔ڵ>I\ģiVTJ*%YoDTYv z,8y&.Qd_L5"SLġٓq!KW6~f-38ћeV+7(̈?ѮMySErY.R5oS|(dXI\|'oqko]$,sg |BΡ kĪ-Ui!RfT[C/FSdh5)MkO\UZ֏#\q%bUI50`=8Ӻ "+-6~69ktҵ)(SF CjrJjhDHZLmRhԹ.>qrˎTJhꈌFRuiڂr WmiI*/(̌$Gks؀GFcSAiҍ>qNy5;{gӠSFي0[A6[O\!qF!+M좹\̮?@Wl:I 26h^dYUݏ!GBQ! m RTj3V>Q3>Е%JRR3IDG@BSMpQOrT jĿS-{ȖlF5)DQsO;:asٯiʝ $BT$0_JRJu59N>xԒp+#6Vm$!{Ir.f`3 =~t+[} !`@}C8~u "*0_eSy~@UzRaͽQK?33Uӵ+aRy4ғJT^QI; =vHRvLPqW$JMuZ5,]&Lɼ?8PV#V%m/SߥD+b1LN4\$y؏_kQE}4*LJ8e"ϸ43KI>W|+I茥^q?NmYiwѵ_//[5V!MB4xRSTՍKSF"B}cjFqӋ\t̼2SFTDe2VsNHekJM)QyFdfY$J>;[fE:5& LƔn)tsQߧC=>4h0؎VIB~\P%hQ)*+Dw#/}J2UaPKC%V5DGR?Ydv;8IF'eOd*ӰUJ,#&Rv&okԣ+t53k*MuDƘpCnj.$/w!$"oO%]Z{hJ䰗 (3dGn`zn{fth&p lDk[h-\J 5&צ¦ď)ie)q RIqko]{w |BΡ` W?:pXsoTRv*UZlTQ JhrZtA?oC?>_`U C_4]MT2ʊ%Ly64QH,y ;ZV6E |HmNISV5-MH QICޠ>Jjs6m Z;T⢿Т1E]+zfq)ZJu4Ž yI%S!fDi4Dq?*fCoQ*2StuI)1MT) I32A""II="nOgȈqGO F3Sffffxۙ&S$ŎQPHIv"p{w W B W?:q+\W ,q\|'oI +\sg\|'oqko]$,sg |BΡ qko]{w |BΡ` W?:p{w W B W?:q+\W ,q\|'oI +\sg\|'oqko]$,sg |BΡ qko]{w |BΡ` W?:p{w W B W?:q*3mHe '\)dF^Yl?Ǭ! gl?Ǭ!Fp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ `a=aűp8~-XAlz6cq[gl?Ǭ qko]a=a 5*3d7!.ؒ3>BI cQ~_`PB-IOrT]il5>$'a4 "Ejpmn%: $if׵#,r2 ω7 *bi67FDw%̧d#;eѝZۦ=تm?s}¼+ZW;s/$۲r|;2.BefB(A +>K6Lvr)i/!dm]FIR_oZZۄC6La ki8[x-$"$_1(D.;\*C;oDDē*[fD'MQ$iJѳX"Q5.WӬ9 igO8dH֣""fg )u:$RhɫG|k;&!V61iuh`NFid'ȹ}+V&UDL7a"CDhxrAhQ:=iĔEe!6J.R \bV"TiQ%1OC-,!2#dv;}6EM̱-ȮI($q2l,nYc^MBM3fe&MZÂp Jѥ)[lW fV?[:5t!rDiPfLy(Qk/o~W zVOzSsDɹ& D3)FF53f]A%=%ؙ O;ȬwpTӌh%n[$\ A@rJj7ԅ,$RD)#32JH$W;Xkj]>DqCrrPgy-yYe|qɽ jǤ: $_!=tgߕ PĬH\xIY ?R\Sxң#34,>IyдgU6j "Rm8V"%Y(X-Ga~MaK4~߿SX}0yW, for his inverted feature code contribution. And, the code is copy from evince, and the author is Juanjo Marín. Thanks !!! - Daniel Friesel , for his more beautiful man page - Andrew Kudryashov , for his help about Startup.pdf - Adam , for his test and bug fix. - Stefan Ritter , for his man page of apvlv, his careful test and pack on Debian - Robert Smolinski , for his vimlike tabs code contribution. And, he is a developer of apvlv then. - Robby Workman , for his bug fix about doc directory - grandpa , for his test on windows - Ali Gholami Rudi , for his bug fixes - tocer , for his test on linux and pack on ArchLinux. - pk , for his advices apvlv-0.1.1-Source/Startup.tex100755 1750 1750 27053 11521211167 15371 0ustar00pengdapengda\documentclass[a4paper,12pt]{article} % \usepackage{graphicx} \usepackage[top=2in,bottom=1in,left=1.25in,right=1.25in]{geometry} \usepackage{color} \definecolor{darkblue}{rgb}{0,0,.5} \definecolor{darkred}{rgb}{.5,0,0} \definecolor{indigo}{RGB}{75,0,139} \usepackage[pdftex, colorlinks, % Schrift in Farbe, sonst mit Rahmen bookmarksnumbered, % Inhaltsverzeichnis mit Numerierung bookmarksopen, % offnet das Inhaltsverzeichnis pdfstartview=FitH, % startet mit Seitenbreite linkcolor=darkblue, % standard red citecolor=darkred, % standard green urlcolor=indigo, % standard cyan filecolor=darkblue, % pdftitle={Apvlv Manual}, pdfauthor={Alf, Sebastian}, pdfsubject={Alf's PDF Viewer Like Vim}, pdfcreator={vim & pdflatex}, pdfkeywords={open source software documentation}, pdfproducer={pdflatex}, plainpages=false % to avoid warning: pdfTeX warning (ext4): destination with the same identifier (name{page.1}) has been already used ]{hyperref} % let's agree on a format how we display apvlv's name: \newcommand{\apvlv}{\textsf{Apvlv{ }}} \begin{document} \large \title{Apvlv - Alf's PDF Viewer Like Vim} %\author{version 0.1.1} \author{by Alf \texttt{$<$\href{mailto:naihe2010@gmail.com}{naihe2010@gmail.com}$>$}} \date{\today} %\date{Apvlv is open source and freely distributable} \maketitle{} \begin{center} Current version: 0.1.1\\ \vspace{1cm} \apvlv is open source software (GNU GPLv2) and freely distributable. \vspace{1cm} \rule{\textwidth}{1pt} \begin{tabular}{lll} type & :help info$<$Enter$>$ & for information \\ type & q & for exit \\ type & :help command$<$Enter$>$ & for help on a command \\ type & :help setting$<$Enter$>$ & for help on settings \\ % \end{tabular} \rule{\textwidth}{1pt} \vspace{3cm} {\small Please visit \apvlv's homepage \texttt{\href{http://apvlv.googlecode.com}{http://apvlv.googlecode.com}} for more information, issues and help.} \end{center} \newpage \section{Introduction}\label{intro} \apvlv is open source software, and was created by Alf. It is in active development. %Now, it is still growing. As its name suggests, \apvlv allows you to read your PDF/\-DJVU/\-UMD files in Vim-style! A focus is set on simplicity and minimalistic GUI. This way you have more space for the actual document. \apvlv's key bindings are inspired by the design and high efficiency of Vim commands making its use a joy for all accustomed Vim users. For example, one can use $<$Ctrl-f$>$ to forward page, $<$Ctrl-b$>$ to previous page, 'k','j','h','l' to scroll page up, down, left or right, and so on. Furthermore, \apvlv can understand how many times you want to run the command. E.g. typing '20' and $<$Ctrl-f$>$ will go 20 pages forward. %The only thing you need to do is typing the number before the command. For example, typing '50' and $<$Ctrl-f$>$ will go 50 pages forward, typing '30' and $<$Ctrl-b$>$ will go 30 pages back. Even more practical is \apvlv's ability to show the content of a directory (press 'O') on your system. You're then able to navigate through folders in Vim-style fashion. 'h' and 'l' collapse or expand a directory and pressing 't' will open the selected document in a new tab. %the table of contents upon pressing 't'. This allows you to navigate through the %What's more important is that \apvlv supports view of a directory as content of pdf document. Pressing 'k' or 'j' to move selected up or down, 'h' or 'l' to collapse or expand a dir, and press 't' will open the selected document in a new tab. This documentation introduces you to using \apvlv. Section \ref{gettingstarted} describes installation and invocation of \apvlv. Section \ref{command} summarizes the available commands and key bindings, section \ref{setting} describes the available configurations and section \ref{promtcommand} explains the command prompt (commands that start with ':'). %Do you like it? If yes, continue read the help document. \newpage \section{Getting Started}\label{gettingstarted} \subsection{Installation of \apvlv}\label{sinstall} \apvlv uses GNU Autotools as it's build system, you just need to type \begin{verbatim} # ./configure # make # make install \end{verbatim} in a terminal to install it to \texttt{/usr/local}. If you got error message like \texttt{No package 'poppler-glib'} found, then you might have to install the poppler library by yourself. If you want to install \apvlv in a custom path, use \texttt{./configure --prefix=YOUR CUSTOM PATH} instead of \texttt{./configure}. \subsection{How to start the binary program}\label{sstart} You can run \apvlv by typing '\texttt{apvlv}' in any terminal which is running under X. To open a specific pdf document, run '\texttt{apvlv $<$documentname$>$.pdf}' If you get an error message like 'command not found', make sure the path in which \apvlv's binary is located is in your "PATH" environment variable. If not, run '\texttt{export PATH="/usr/local/bin:\$PATH"}' to append the path. \newpage \section{Command}\label{command} \begin{description} \item o display a file chooser dialog to select a PDF/\-DJVU/\-UMD file to open. \item O select a directory to display. After you selected the directory within the dialog, press enter and \apvlv will recursively search the path for PDFs/DJVUs/UMDs. You will be presented with a vim-style navigation of your folders which allows you to easily access another document. \item R reload the current file. \item r [count] rotate the document page \item G go to end of document, or (preceded by [count]) show page [count] \item gt show next tab \item gT show previous tab \item $<$PageDown$>$ or $<$C-f$>$ [count] go n page(s) forward \item $<$PageUp$>$ or $<$C-b$>$ [count] go n page(s) backward \item $<$C-d$>$ [count] half page forward \item $<$C-u$>$ [count] half previous page \item H scroll to head of page \item M scroll to center of page \item L scroll to end of page \item s [count] skip \item $<$C-p$>$ $<$Up$>$ k [count] scroll up \item $<$C-n$>$ or $<$Down$>$ or $<$C-j$>$ or j [count] scroll down \item $<$BackSpace$>$ or $<$Left$>$ or h [count] scroll left \item $<$Space$>$ or $<$C-l$>$ or l [count] scroll right \item / search for a string. Type and hit $<$enter$>$. \item ? search for a string, backwards. \item f Toggle full screen mode. % If \apvlv is in full screen mode, switch to normal mode. Other wise, switch to full screen. \item zi zoom in. \item zo zoom out. \item zw zoom to fit width. \item zh zoom to fit height (full page). \item m Mark the read position and name it by pressing a character. \\ That is, press 'ma' will mark the current position to a, and you can return here by press 'a. \item ' Goto the position indicated by a character, i.e. press 'a to go to the position a. \\ %The next key be pressed must had been marked before. The character has to be marked by 'm' before (see above). \item '' Return to the previous position \item $<$C-w$>$ q \item $<$C-w$>$ $<$C-Q$>$ Close the current tab (other tabs will not be affected) \item $<$C-w$>$ $<$C-w$>$ move to the next window (currently broken). \item $<$C-w$>$ k move to the up window. \item $<$C-w$>$ j move to the down window. \item $<$C-w$>$ h move to the left window. \item $<$C-w$>$ l move to the right window. \item $<$C-w$>$ - make the current window smaller. \item $<$C-w$>$ + make the current window bigger. \end{description} \noindent All commands can be mapped to other keys. For example, if you put \\ 'map $<$C-n$>$ o'\\ in your .apvlvrc. Then, typing $<$Ctrl-n$>$ will run the 'o' command, that is, show a file chooser dialog to select a PDF/DJVU/UMD file to open.\\ \noindent Be careful, do NOT map a command to itself! 'map god god' will make the application to loop test the command 'god' for ever. \newpage \section{Setting}\label{setting} \apvlv supports settings set in a file called .apvlvrc. \begin{description} \item fullscreen=yes/no If set yes, \apvlv will be in full screen mode after startup. \item width=$<$int$>$ When fullscreen is not set to yes, this is the window width in pixels. \item height=$<$int$>$ When fullscreen is not set to yes, this is the window height in pixels. \item defaultdir=$<$path$>$ When display the file open dialog ('o'), this is the default directory. \item zoom < normal | fitwidth | fitheight | = > Zoom settings can be set in four different modes, select one: \begin{enumerate} \item normal the default zoom value will be set by the application itself. \item fitwidth zoom will be set to fit the page width to the window width. \item fitheight zoom will set to fit the page height to the window height. \item custom set a custom value e.g. zoom=1.0, zoom=1.2, zoom=0.8. \end{enumerate} \item content=yes/no Set if use content view as first \item continuous=yes/no set a pdf page continuous or not. This value will be avoid when the autoscrollpage is set to no. \item continuouspad=2 set a padding in the continuous view of page \item autoscrollpage=yes/no set whether auto scroll page when k,j to a page's tail or head \item autoscrolldoc=yes/no set if auto scroll doc from 1st page when goto the last page \item noinfo=yes/no set whether disable ~/.apvlvinfo \item pdfcache=4 set pdf object cache size \item scrollbar=no set not scrollbar or do \item visualmode=no set not use visual mode to select and copy text or do \item wrapscan=yes set wrapscan to search text or not \item doubleclick This argument has 4 types. \begin{enumerate} \item none Selection nothing \item word Selection a word under the curcor to clipboard \item line Selection a line under the curcor to clipboard \item page Selection a page under the curcor to clipboard \item guioptions=< m | T > Weather show menu and tool bar. m means menu bar, T means tool bar. \item autoreload If auto reload document after some seconds \item reverted If reverted pdf page \end{enumerate} \end{description} \newpage \section{Prompt Command}\label{promtcommand} \begin{description} \item :h[elp] display the help pdf document. \item :h[elp] info display the help pdf document about the introduction. \item :h[elp] command display the help pdf document about the command. \item :h[help] setting display the help pdf document about the setting in the .apvlvrc \item :h[elp] prompt display the help pdf document about the prompt command. \item :q[uit] close the current window.\\ If the window is the top level window, quit the program. \item o[pen] 'filename' open a file which named 'filename'. \item w[rite] 'filename' save the current document to file which named 'filename'. \item doc 'filename' load the 'filename' to current window. \item :TOtext translate the current page to a text file. \item :pr[int] print the current document. \item :TOtext 'filename' translate page to a text file named 'filename'. \item :tabnew create a new tab \item :sp split the current window into two windows. \item :vsp split the current window into two horizon windows. \item :fp \item :forwardpage go forward some pages. \item :bp \item :prewardpage go preward some page. \item :g \item :goto go to a page. \item :set [no]cache set if use cache module. If you don't feel scroll slowly, you don't need set this to on. \item :z[oom] fitwidth/fitheight/value zoom to fit width, fit height or a custom value \item :[number] go to a page number \end{description} \newpage \section{About}\label{about} \large \begin{tabular}{l} Website: \texttt{\href{http://apvlv.googlecode.com}{http://apvlv.googlecode.com}} \\ Author: Alf \texttt{\href{mailto:naihe2010@gmail.com}{$<$naihe2010@gmail.com$>$}} \\ Blog: \texttt{\href{http://naihe2010.cublog.cn}{http://naihe2010.cublog.cn}} \end{tabular} \end{document} apvlv-0.1.1-Source/TODO100644 1750 1750 452 11521211167 13624 0ustar00pengdapengda. Bug fix. . Regex search, multiple search. . Word moving, put a curcor in the document. and 'k','j' ... moves it. . Press 'v' to select a text area, and then TOtext them or copy them to clipboard. . Other document type, like .gv, word, ????? . Edit file???????? apvlv-0.1.1-Source/icons/dir.png100644 1750 1750 3774 11521211167 15565 0ustar00pengdapengdaPNG  IHDR00WbKGD{ḷIDATx۫W?{fNNB!4Q-^ ""D)O&PJmb4Z&95i697{-e֞ߜ) goΞ={w]k5s;U@?;)ӷϿ?,paM'P 7676Y_7=vx4~׸\9Qs_o?/S?|wߋ@34x˓8QPUTWh %ʎ"'q=  <,q yEWUкFP`;,ϩ/ro_~-7|^ET/YHcAQAxM7oN8~ wݽ/Pxd:kF6Y^]e2sq ]hyeuD4RUUp1.X ƠpWoPuEU9*WǕ%VM.Zv9^[O|7~GQTm[TCHW"I*x5 9`aaq6ti_L>y8~a\{-'Z +D*A~6W^S?чwoajB§?ukA0 ~,Sԇ5k<ǷE[ {`3w??H3g[_UUfg^rBNv!ڝ"jꂣZBqQGg?{sal,B vU2+FwQ3ǞDq,cTD&L`jpoEM+bA /Vxs5d D:NTgE]);1 GɊ4O#]0\=AZ+ƝW$T;m t}eg bU mJ(Q7+cb,)gJ]tfRDOxIa%m2A1Wxigt!2kfi: .4$< ]90Lh6A;@P\.ٕ6L#0q\Gs|fS Xˤ2;V )(VĂ-] -0A\!CfDp MgCV+ }fK2X{(iUUD﹬,LӪ+}f!Xvb$O X@N v%%V_t[ˮ;aJl-j`AԐ{~G|uU9pULI.^x  Vh5_|H֍em=5Eg9ǙӿF@nO~OL>p8sM M|1TҹMBYC"O=6jڟoMzy} Qs;[o&$J X*U7 tEIz|=uFM֖cWrޢ>kαs_MGCIENDB`apvlv-0.1.1-Source/icons/pdf.png100644 1750 1750 2443 11521211167 15550 0ustar00pengdapengdaPNG  IHDR szzsBIT|dIDATX[le盝iӲlRX,m|2ф$|AbL *x{(CbjK\rmwwf>ig~s9?9[${=OA:#E(#u>xGQuR/u^:|{חc/TxlL.\=5Z{/xP>9ƾ O< RTKi ǀ @.5#°3X{^uI6=t;s9Ξf®оBcI2,|~ rMoAp0#&Z) ag|(%,)e18NWwߘaވ{IEG']g@81ļ XIP-uWB~Qv>$Rʵ ɥohh~0q D7:AXBB^ ďo!Gj]YL,u']F 0;7?nͶ-2u72??2,JƎogou::h\JAfغXPaN/w)%|ϋX@(l<7t=IENDB`apvlv-0.1.1-Source/icons/reg.png100644 1750 1750 3403 11521211167 15551 0ustar00pengdapengdaPNG  IHDR04̓bKGDCIDATx՚KoWC4³*HtEʢ,RB+O]Y#P%XtQHx4< MTv`ĵӅ3;wSP+d߹w|?5w,N`u wP(|b(cccrQ_{@*VܺuKDDfffފ@Jr,bQdttW8%R!"H* ="ɰyf._ X Mlݺu^G\-[044DkkSЗ۷oϋ~abbLM6q :::J~y58yGww77~M85Bs&0 J%sccc\zRĆ ݜ:u {`O&hDhڪy_#GP,QY={| Ju.D>/_N.X\8q߸dF<zlP=QpF_]+!JQTi<8v.`B.rTz*j"U* |t/7,6`*y5SumۦYE8x2ո(fhnnv"(Tbd2&=S_+W.t67ѬEĚ@{}I9'ۿe$,1q>veO|jTytXD)U|DWDXL2,\kI5 $;w͛׆2.Nf`%X!+"ݻϟ%AH~:--UH*(HI|hDbg.\8ϲe^@$fۘML&@H)RT,ʈ5F6%B LNd׮ŋ5HB8i\LNZsZzp\B^'ĶCzXHk. $p?ԜkqUUx$!U}fr1IRcbDgYjM2 [j\Lb&-[IaWJ !vOgwe+l$k KYbbqR"S\4Bgck(Y(Da:khhrָ%Mk!~^|QFљ8؊ð)/ǡCd'B##tiFK(n&6MBJ&S(Ξ=Ú5%$Z%sypn)MCg9n[rp0'C/[ܫ*"ўXOnQ|b"̙_Xv]rzPv۞!Bx߾rO-r}ŵopkJnϟ?GW (Lpzh˸[Xӧfݺ=$0;--u34rps=٩WÇIC\ڀL.~}]rIeޅ)!Т.!k)0CHP*MZ0/dm(C@eIENDB`apvlv-0.1.1-Source/COPYING100644 1750 1750 43103 11521211167 14227 0ustar00pengdapengda GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. apvlv-0.1.1-Source/apvlvrc.example100644 1750 1750 2755 11521211167 16216 0ustar00pengdapengda" some map " map n to to goto next page "map n " and p to prepage "map p " map I to zi, and O to zo "map I zi "map O zo " if start apvlv as fullscreen mode, default is no set fullscreen=no " zoom value, default is fitwidth " zoom has 4 styles " a float type number " fitwidth " fitheight " normal "set zoom=fitwidth " set window size set width=800 set height=600 " set command timeout between two key press set commandtimeout=2000 " set default dir set defaultdir=C:\ " set if use content view set content=yes " set weather use continuous view " make sure the autoscrollpage is set to "yes" if you want to set this to yes set continuous=yes " set a pad to continuous page set continuouspad=2 " set if auto scroll page when at the end or begin of one pdf page set autoscrollpage=yes " set if auto scroll doc from 1st page when goto the last page set autoscrolldoc=yes " set if disable ~/.apvlvinfo, default is no set noinfo=no " set pdf object cache size set pdfcache = 4 " set if use right and bottom scrollbar set scrollbar = no " set if use visual mode to select and copy text set visualmode = no " set if wrapscan text set wrapscan = yes " set double click action " option value is 'word', 'line' or 'page' set doubleclick = page " set GUI options " m means menu, T means toolbar " set guioptions = " set if use auto reload document " > 0 means auto reload after some seconds. = 0 means not auto reload " set autoreload = 3 " set if reverted pdf page " set reverted = no apvlv-0.1.1-Source/AUTHORS100644 1750 1750 32 11521211167 14156 0ustar00pengdapengdaAlf apvlv-0.1.1-Source/src/ApvlvInfo.hpp100644 1750 1750 3126 11521211167 16361 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvInfo.hpp * * Author: Alf */ /* @date Created: 2010/02/23 14:56:21 Alf*/ #ifndef _APVLV_INFO_H_ #define _APVLV_INOF_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include #include using namespace std; namespace apvlv { struct infofile { int page; int skip; double rate; string file; }; class ApvlvInfo { public: ApvlvInfo (const char *file); ~ApvlvInfo (); bool update (); infofile *file (int); infofile *file (const char *); bool file (int, double, const char *, int); private: string mFileName; GSList *mFileHead; int mFileMax; bool ini_add_position (const char *); }; extern ApvlvInfo *gInfo; }; #endif apvlv-0.1.1-Source/src/main.cpp100644 1750 1750 11676 11521211167 15425 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /*@CPPFILE main.cpp Apvlv start at this. * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvView.hpp" #include "ApvlvCmds.hpp" #include "ApvlvParams.hpp" #include "ApvlvInfo.hpp" #include "ApvlvUtil.hpp" #include #ifndef WIN32 #include #endif #include #include using namespace apvlv; #if defined WIN32 && defined NDEBUG #pragma comment (linker, "/subsystem:windows") #pragma comment (linker, "/ENTRY:mainCRTStartup") #endif #ifndef WIN32 static void usage_exit () { fprintf (stdout, "%s Usage:\n" "%s\n" "Please send bug report to %s\n", PACKAGE_NAME, "\t-h display this and exit\n" "\t-v display version info and exit\n" "\t-c [file] set user configuration file\n", PACKAGE_BUGREPORT); } static void version_exit () { fprintf (stdout, "%s %s-%s\n" "Please send bug report to %s\n" "\n", PACKAGE_NAME, PACKAGE_VERSION, RELEASE, PACKAGE_BUGREPORT); } #endif static int parse_options (int argc, char *argv[]) { gchar *ini; #ifdef WIN32 ini = absolutepath (inifile.c_str ()); if (ini != NULL) { gParams->loadfile (ini); g_free (ini); } return 1; #else int c, index; static struct option long_options[] = { {"config", required_argument, NULL, 'c'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'v'}, {0, 0, 0, 0} }; index = 0; ini = NULL; while ((c = getopt_long (argc, argv, "c:hv", long_options, &index)) != -1) { switch (c) { case 'c': ini = absolutepath (optarg); break; case 'h': usage_exit (); return -1; case 'v': version_exit (); return -1; default: errp ("no command line options"); return -1; } } if (ini == NULL) { ini = absolutepath (inifile.c_str ()); } /* * load the global sys conf file * */ gchar *sysini = g_strdup_printf ("%s/%s", SYSCONFDIR, "apvlvrc"); if (sysini) { gParams->loadfile (sysini); g_free (sysini); } /* * load the user conf file * */ if (ini != NULL) { gParams->loadfile (ini); g_free (ini); } return optind; #endif } int main (int argc, char *argv[]) { setlocale (LC_ALL, ""); ApvlvCmds sCmds; gCmds = &sCmds; ApvlvParams sParams; gParams = &sParams; gchar *infopath = absolutepath ("~/.apvlvinfo"); ApvlvInfo sInfo (infopath); g_free (infopath); gInfo = &sInfo; #ifdef _WIN32 gchar *temp = absolutepath (iconpdf.c_str ()); iconpdf = temp; g_free (temp); temp = absolutepath (icondir.c_str ()); icondir = temp; g_free (temp); temp = absolutepath (iconreg.c_str ()); iconreg = temp; g_free (temp); #endif int opt = parse_options (argc, argv); if (opt < 0) { errp ("Parse options failed.\n"); return 1; } gchar *path; bool ishelppdf = false; if (opt > 0 && argc > opt) { path = argv[opt]; opt++; } else { path = (gchar *) helppdf.c_str (); ishelppdf = true; } gchar *rpath = g_locale_to_utf8 (path, -1, NULL, NULL, NULL); if (rpath == NULL) { errp ("Convert path: '%s' to utf8 failed.\n", path); return 1; } path = absolutepath (rpath); g_free (rpath); if (path == NULL) { errp ("Convert '%s' to absolute path failed.\n", rpath); return 1; } if (g_file_test (path, G_FILE_TEST_IS_REGULAR) == FALSE) { errp ("File '%s' is not readble.\n", path); g_free (path); return 1; } gtk_init (&argc, &argv); ApvlvView sView (path); if (ishelppdf) { helppdf = path; } g_free (path); gView = &sView; while (opt < argc) { path = absolutepath (argv[opt++]); if (path == NULL) { continue; } if (gView->loadfile (path) == false) { errp ("Can't open document: %s", path); } g_free (path); } gtk_main (); return 0; } apvlv-0.1.1-Source/src/ApvlvWindow.hpp100644 1750 1750 5650 11521211167 16741 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvWindow.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_WINDOW_H_ #define _APVLV_WINDOW_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvCore.hpp" #include "ApvlvDoc.hpp" #include #include using namespace std; namespace apvlv { class ApvlvCore; class ApvlvWindow { public: ApvlvWindow (ApvlvCore * core); ~ApvlvWindow (); /* WE operate the AW_DOC window * Any AW_SP, AW_VSP are a virtual window, just for contain the AW_DOC window * AW_NONE is a empty window, need free * So, ANY user interface function can only get the AW_DOC window * */ enum windowType { AW_SP, AW_VSP, AW_CORE, AW_NONE } type; ApvlvWindow *birth (bool vsp, ApvlvCore * core = NULL); ApvlvWindow *unbirth (ApvlvWindow *, ApvlvWindow *); bool istop (); void runcommand (int times, const char *, int argu); GtkWidget *widget (); ApvlvCore *getCore (); void setCore (ApvlvCore * core); void getsize (int *w, int *h); void setsize (int wid, int hei); void smaller (int times = 1); void bigger (int times = 1); ApvlvWindow *getneighbor (int count, guint key); ApvlvWindow *getnext (int num); returnType process (int times, guint keyval); static void setcurrentWindow (ApvlvWindow * pre, ApvlvWindow * win); static void delcurrentWindow (); static ApvlvWindow *currentWindow (); ApvlvWindow *m_parent, *m_son, *m_daughter; private: inline ApvlvWindow * getkj (int num, bool next); inline ApvlvWindow *gethl (int num, bool next); inline gboolean resize_children (); static gboolean apvlv_window_resize_children_cb (gpointer data); static gboolean apvlv_window_paned_resized_cb (GtkWidget * wid, GdkEventButton * event, ApvlvWindow * win); static ApvlvWindow *m_curWindow; bool mIsClose; ApvlvCore *mCore; GtkWidget *mPaned; int mWidth, mHeight; }; } #endif apvlv-0.1.1-Source/src/ApvlvCore.cpp100644 1750 1750 26153 11521211167 16376 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CFILE ApvlvCore.cpp * * Author: Alf */ /* @date Created: 2009/01/04 09:34:51 Alf*/ #include "ApvlvParams.hpp" #include "ApvlvView.hpp" #include "ApvlvCore.hpp" #include #include #include namespace apvlv { class ApvlvView; extern ApvlvView *gView; ApvlvCore::ApvlvCore () { mInuse = true; mReady = false; mProCmd = 0; mRotatevalue = 0; mSearchResults = NULL; mSearchStr = ""; mVbox = gtk_vbox_new (FALSE, 0); g_object_ref (mVbox); mScrollwin = gtk_scrolled_window_new (NULL, NULL); if (gParams->valueb ("scrollbar")) { gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mScrollwin), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); } else { gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (mScrollwin), GTK_POLICY_NEVER, GTK_POLICY_NEVER); } mVaj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (mScrollwin)); mHaj = gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (mScrollwin)); mReloadTimer = 0; mCheckMD5 = NULL; if (gParams->valuei ("autoreload") > 0) { mReloadTimer = g_timeout_add (gParams->valuei ("autoreload") * 1000, apvlv_core_check_reload, this); } } ApvlvCore::~ApvlvCore () { if (mReloadTimer) { g_source_remove (mReloadTimer); mReloadTimer = 0; } if (mCheckMD5) { g_free (mCheckMD5); mCheckMD5 = NULL; } g_object_unref (mVbox); } bool ApvlvCore::reload () { return true; } static gboolean add_token (const char *name, void *data) { string *str = (string *) data; str->append (name); return TRUE; } gchar *ApvlvCore::checkmd5 () { #ifdef WIN32 struct _stat32 sbuf[1]; #else struct stat sbuf[1]; #endif int rt = g_stat (mFilestr.c_str (), sbuf); if (rt < 0) { gView->errormessage ("stat file: %s error.", mFilestr.c_str ()); return NULL; } time_t now = time (NULL); if (S_ISDIR (sbuf->st_mode)) { string data; walkdir (mFilestr.c_str (), add_token, &data); gchar *md5 = g_compute_checksum_for_string (G_CHECKSUM_MD5, data.c_str (), -1); return md5; } else if (now - sbuf->st_mtime < 2) { debug ("File is modifing, skiped.\n"); return mCheckMD5; } else { guchar *data = new guchar[sbuf->st_size]; ifstream ifs (mFilestr.c_str (), ios::binary); if (ifs.is_open ()) { ifs.read ((char *) data, sbuf->st_size); ifs.close (); } gchar *md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5, data, sbuf->st_size); delete[]data; return md5; } return NULL; } gboolean ApvlvCore::apvlv_core_check_reload (gpointer data) { ApvlvCore *core = (ApvlvCore *) data; if (core->mInuse == false) { return TRUE; } if (core->mCheckMD5 == NULL) { core->mCheckMD5 = core->checkmd5 (); return TRUE; } else { gchar *newmd5 = core->checkmd5 (); if (newmd5 == NULL) { debug ("%d: get check sum failed", time (NULL)); return TRUE; } if (strcmp (newmd5, core->mCheckMD5) == 0) { debug ("%d: file is not changed.", time (NULL)); g_free (newmd5); return TRUE; } else { debug ("%d: file is modified, reload it.", time (NULL)); gView->infomessage ("Contents is modified, apvlv reload it automatically"); g_free (core->mCheckMD5); core->mCheckMD5 = newmd5; core->reload (); } } return TRUE; } void ApvlvCore::inuse (bool use) { mInuse = use; if (mInuse == false && gView->hasloaded (filename (), type ()) == false) { debug ("core :%p is not needed, delete it\n", this); delete this; } } bool ApvlvCore::inuse () { return mInuse; } int ApvlvCore::type () { return mType; } returnType ApvlvCore::process (int has, int ct, guint key) { return MATCH; } void ApvlvCore::setsize (int w, int h) { gtk_widget_set_size_request (widget (), w, h); gtk_widget_set_size_request (mScrollwin, w, h - 16); mStatus->setsize (w, 15); mWidth = w; mHeight = h; } ApvlvCore *ApvlvCore::copy () { return NULL; } const char *ApvlvCore::filename () { return mReady && mFilestr.length () > 0 ? mFilestr.c_str () : NULL; } gint ApvlvCore::pagenumber () { return mPagenum + 1; } gint ApvlvCore::getrotate () { return mRotatevalue; } gdouble ApvlvCore::zoomvalue () { return mZoomrate; } ApvlvFile *ApvlvCore::file () { return mFile; } bool ApvlvCore::writefile (const char *name) { if (mFile != NULL) { debug ("write %p to %s", mFile, name); return mFile->writefile (name ? name : filename ()); } return false; } bool ApvlvCore::loadfile (const char *file, bool check) { return false; } GtkWidget *ApvlvCore::widget () { return mVbox; } void ApvlvCore::showpage (gint p, gdouble s) { } void ApvlvCore::refresh () { } double ApvlvCore::scrollrate () { double maxv = mVaj->upper - mVaj->lower - mVaj->page_size; double val = mVaj->value / maxv; if (val > 1.0) { return 1.00; } else if (val > 0.0) { return val; } else { return 0.00; } } gboolean ApvlvCore::scrollto (double s) { if (!mReady) return FALSE; if (mVaj->upper != mVaj->lower) { double maxv = mVaj->upper - mVaj->lower - mVaj->page_size; double val = maxv * s; gtk_adjustment_set_value (mVaj, val); mStatus->show (); return TRUE; } else { debug ("fatal a timer error, try again!"); return FALSE; } } void ApvlvCore::scrollup (int times) { if (!mReady) return; gdouble val = gtk_adjustment_get_value (mVaj); gdouble sub = mVaj->upper - mVaj->lower; mVrate = sub / mLines; if (val - mVrate * times > mVaj->lower) { gtk_adjustment_set_value (mVaj, val - mVrate * times); } else if (val > mVaj->lower) { gtk_adjustment_set_value (mVaj, mVaj->lower); } else { if (gParams->valueb ("autoscrollpage")) { if (gParams->valueb ("continuous")) { showpage (mPagenum - 1, ((mVaj->upper / 2) - mVrate * times) / (sub - mVaj->page_size)); } else { showpage (mPagenum - 1, 1.0); } } } mStatus->show (); } void ApvlvCore::scrolldown (int times) { if (!mReady) return; gdouble val = gtk_adjustment_get_value (mVaj); gdouble sub = mVaj->upper - mVaj->lower; mVrate = sub / mLines; if (val + mVrate * times + mVaj->page_size < mVaj->upper) { gtk_adjustment_set_value (mVaj, val + mVrate * times); } else if (val + mVaj->page_size < mVaj->upper) { gtk_adjustment_set_value (mVaj, mVaj->upper - mVaj->page_size); } else { if (gParams->valueb ("autoscrollpage")) { if (gParams->valueb ("continuous")) { showpage (mPagenum + 1, (sub - mVaj->page_size) / 2 / sub); } else { showpage (mPagenum + 1, 0.0); } } } mStatus->show (); } void ApvlvCore::scrollleft (int times) { if (!mReady) return; mHrate = (mHaj->upper - mHaj->lower) / mChars; gdouble val = mHaj->value - mHrate * times; if (val > mVaj->lower) { gtk_adjustment_set_value (mHaj, val); } else { gtk_adjustment_set_value (mHaj, mHaj->lower); } } void ApvlvCore::scrollright (int times) { if (!mReady) return; mHrate = (mHaj->upper - mHaj->lower) / mChars; gdouble val = mHaj->value + mHrate * times; if (val + mHaj->page_size < mHaj->upper) { gtk_adjustment_set_value (mHaj, val); } else { gtk_adjustment_set_value (mHaj, mHaj->upper - mHaj->page_size); } } bool ApvlvCore::hascontent () { return false; } bool ApvlvCore::usecache () { return false; } void ApvlvCore::usecache (bool use) { } bool ApvlvCore::print (int ct) { return false; } bool ApvlvCore::totext (const char *name) { return false; } bool ApvlvCore::rotate (int ct) { return false; } void ApvlvCore::markposition (const char s) { } void ApvlvCore::setzoom (const char *z) { } void ApvlvCore::jump (const char s) { } void ApvlvCore::nextpage (int times) { } void ApvlvCore::prepage (int times) { } void ApvlvCore::halfnextpage (int times) { } void ApvlvCore::halfprepage (int times) { } bool ApvlvCore::search (const char *str, bool reverse) { return false; } bool ApvlvCore::continuous () { return false; } void ApvlvCore::gotolink (int ct) { } int ApvlvCore::getskip () { return mSkip; } void ApvlvCore::setskip (int ct) { mSkip = ct; } void ApvlvCore::returnlink (int ct) { } void ApvlvCore::setactive (bool act) { mActive = act; if (mActive && filename () && gView) { gchar *base = g_path_get_basename (filename ()); gView->settitle (base); g_free (base); } } ApvlvCoreStatus::ApvlvCoreStatus () { mHbox = gtk_hbox_new (FALSE, 0); } ApvlvCoreStatus::~ApvlvCoreStatus () { } GtkWidget *ApvlvCoreStatus::widget () { return mHbox; } void ApvlvCoreStatus::active (bool act) { } void ApvlvCoreStatus::setsize (int w, int h) { } void ApvlvCoreStatus::show () { } } apvlv-0.1.1-Source/src/ApvlvUtil.cpp100644 1750 1750 13672 11521211167 16425 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CFILE ApvlvUtil.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvUtil.hpp" #include #ifndef WIN32 #include #endif #ifdef WIN32 # include #endif #include #include using namespace std; namespace apvlv { #ifdef WIN32 string helppdf = "~\\Startup.pdf"; string iniexam = "~\\apvlvrc.example"; string iconreg = "~\\icons\\reg.png"; string icondir = "~\\icons\\dir.png"; string iconpdf = "~\\icons\\pdf.png"; string inifile = "~\\_apvlvrc"; string sessionfile = "~\\_apvlvinfo"; #else string helppdf = string (DOCDIR) + "/Startup.pdf"; string iniexam = string (DOCDIR) + "/apvlvrc.example"; string iconreg = string (DOCDIR) + "/icons/reg.png"; string icondir = string (DOCDIR) + "/icons/dir.png"; string iconpdf = string (DOCDIR) + "/icons/pdf.png"; string inifile = "~/.apvlvrc"; string sessionfile = "~/.apvlvinfo"; #endif // Converts the path given to a absolute path. // Warning: The string is returned a new allocated buffer, NEED TO BE g_free char *absolutepath (const char *path) { char abpath[PATH_MAX]; if (g_path_is_absolute (path)) { return g_strdup (path); } if (*path == '~' && *(path + 1) == PATH_SEP_C) { const gchar *home; #ifdef WIN32 home = g_win32_get_package_installation_directory_of_module (NULL); #else home = getenv ("HOME"); if (home == NULL) { home = g_get_home_dir (); } #endif if (home != NULL) { g_snprintf (abpath, sizeof abpath, "%s%s", home, ++path); } else { debug ("Can't find home directory, use current"); g_snprintf (abpath, sizeof abpath, "%s", path + 2); } } else { const gchar *pwd; pwd = g_get_current_dir (); if (pwd != NULL) { g_snprintf (abpath, sizeof abpath, "%s/%s", pwd, path); } else { debug ("Can't find current directory, use current"); g_snprintf (abpath, sizeof abpath, "%s", path); } } return g_strdup (abpath); } gboolean walkdir (const char *name, gboolean (*cb) (const char *, void *), void *usrp) { GDir *dir = g_dir_open (name, 0, NULL); if (dir == NULL) { debug ("Open dir: %s failed", name); return FALSE; } const gchar *token; while ((token = g_dir_read_name (dir)) != NULL) { gchar *subname = g_strjoin (PATH_SEP_S, name, token, NULL); if (subname == NULL) { continue; } if (g_file_test (subname, G_FILE_TEST_IS_REGULAR) == TRUE) { if (cb (subname, usrp) == FALSE) { return FALSE; } } else if (g_file_test (subname, G_FILE_TEST_IS_DIR) == TRUE) { if (walkdir (subname, cb, usrp) == FALSE) { return FALSE; } } } g_dir_close (dir); return TRUE; } // Copy a file bool filecpy (const char *dst, const char *src) { gchar *content; gchar *s = absolutepath (src); gchar *d = absolutepath (dst); bool ok = false; gboolean ret = g_file_get_contents (s, &content, NULL, NULL); if (ret == TRUE) { ret = g_file_set_contents (d, content, -1, NULL); g_free (content); ok = ret; } g_free (s); g_free (d); return ok; } // replace a widget with a new widget // return the parent widget GtkWidget *replace_widget (GtkWidget * owid, GtkWidget * nwid) { GtkWidget *parent = gtk_widget_get_parent (owid); debug ("parent: %p, owid: %p, nwid: %p", parent, owid, nwid); gtk_container_remove (GTK_CONTAINER (parent), owid); gtk_container_add (GTK_CONTAINER (parent), nwid); gtk_widget_show_all (parent); return parent; } void logv (const char *level, const char *file, int line, const char *func, const char *ms, ...) { char p[0x1000], temp[0x100]; va_list vap; g_snprintf (temp, sizeof temp, "[%s] %s: %d: %s(): ", level, file, line, func); va_start (vap, ms); vsnprintf (p, sizeof p, ms, vap); va_end (vap); cerr << temp << p << endl; } int apvlv_system (const char *str) { #ifndef WIN32 int ret; pid_t pid; int status; pid = fork (); ret = -1; if (pid < 0) { errp ("Can't fork\n"); } else if (pid == 0) { gchar **argv; while (!isalnum (*str)) str++; argv = g_strsplit_set (str, " \t", 0); if (argv == NULL) { exit (1); } debug ("Exec path: (%s) argument [%d]\n", argv[0], g_strv_length (argv)); ret = execvp (argv[0], argv); g_strfreev (argv); errp ("Exec error\n"); } else { ret = wait4 (pid, &status, 0, NULL); } return ret; #else return WinExec (str, SW_NORMAL); #endif } } apvlv-0.1.1-Source/src/ApvlvDir.hpp100644 1750 1750 6142 11521211167 16205 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CFILE ApvlvDir.hpp * * Author: Alf */ /* @date Created: 2009/01/03 23:27:52 Alf*/ #ifndef _APVLV_DIR_ #define _APVLV_DIR_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvCore.hpp" #include "ApvlvWindow.hpp" namespace apvlv { class ApvlvDir; class ApvlvDirNode { public: ApvlvDirNode (GtkTreeIter *, gint); ApvlvDirNode (GtkTreeIter *, bool isdir, const char *, const char *); ~ApvlvDirNode (); // // Get the destination bool dest (const char **rpath, int *pagenum); // // Get the string const char *phrase (); // // Get the gtk tree iter const GtkTreeIter *iter (); private: GtkTreeIter itr[1]; gint mPagenum; /* -1 means dir, 0 means file, > 0 means page num */ char filename[0x100]; char *realname; }; class ApvlvDir; class ApvlvDirStatus:public ApvlvCoreStatus { public: ApvlvDirStatus (ApvlvDir *); ~ApvlvDirStatus (); void active (bool act); void setsize (int, int); void show (); private: ApvlvDir * mDoc; #define AD_STATUS_SIZE 4 GtkWidget *mStlab[AD_STATUS_SIZE]; }; class ApvlvDir:public ApvlvCore { public: ApvlvDir (int w, int h); ~ApvlvDir (); bool loadfile (const char *file, bool check = true); void setactive (bool act); returnType process (int hastimes, int times, guint keyval); private: returnType subprocess (int ct, guint key); bool reload (); bool enter (guint key); void scrollup (int times); void scrolldown (int times); void scrollleft (int times); void scrollright (int times); bool search (const char *str, bool reverse = false); bool walk_file_index (GtkTreeIter * titr, ApvlvFileIndexIter iter); bool walk_dir_path_index (GtkTreeIter * titr, const char *path); static void apvlv_dir_on_changed (GtkTreeSelection *, ApvlvDir *); static gboolean apvlv_dir_first_select_cb (ApvlvDir *); gint mFirstSelTimer; ApvlvFileIndex *mIndex; GList *mDirNodes; GtkWidget *mDirView; GtkTreeStore *mStore; GtkTreeIter mPrevIter, mCurrentIter; GtkTreeSelection *mSelection; }; } #endif apvlv-0.1.1-Source/src/ApvlvCore.hpp100644 1750 1750 10661 11521211167 16400 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @PPCFILE ApvlvCore.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_CORE_H_ #define _APVLV_CORE_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvFile.hpp" #include "ApvlvUtil.hpp" #include #include #include using namespace std; namespace apvlv { class ApvlvCore; class ApvlvCoreStatus { public: ApvlvCoreStatus (); virtual ~ ApvlvCoreStatus (); virtual GtkWidget *widget (); virtual void active (bool act); virtual void setsize (int w, int h); virtual void show (); protected: GtkWidget * mHbox; }; class ApvlvCore { public: ApvlvCore (); virtual ~ ApvlvCore (); virtual bool reload (); virtual void inuse (bool use); virtual bool inuse (); virtual int type (); virtual GtkWidget *widget (); virtual ApvlvCore *copy (); virtual ApvlvFile *file (); virtual bool loadfile (const char *file, bool check = true); virtual const char *filename (); virtual bool writefile (const char *); virtual gint getrotate (); virtual gint pagenumber (); virtual void showpage (gint, gdouble s = 0.00); virtual void refresh (); virtual gdouble zoomvalue (); virtual void setactive (bool act); virtual gdouble scrollrate (); virtual gboolean scrollto (double s); virtual void scrollup (int times); virtual void scrolldown (int times); virtual void scrollleft (int times); virtual void scrollright (int times); virtual bool hascontent (); virtual bool usecache (); virtual void usecache (bool use); virtual bool print (int ct); virtual bool totext (const char *name); virtual bool rotate (int ct = 90); virtual void markposition (const char s); virtual void setzoom (const char *z); virtual void jump (const char s); virtual void nextpage (int times = 1); virtual void prepage (int times = 1); virtual void halfnextpage (int times = 1); virtual void halfprepage (int times = 1); virtual bool search (const char *str, bool reverse = false); virtual bool continuous (); virtual void gotolink (int ct); virtual void returnlink (int ct); virtual int getskip (); virtual void setskip (int ct); virtual void setsize (int wid, int hei); virtual returnType process (int has, int times, guint keyval); protected: ApvlvFile * mFile; bool mReady; bool mInuse; int mType; gchar *mCheckMD5; guint mReloadTimer; string mFilestr; guint mProCmd; double mScrollvalue; int mSearchPagenum; char mSearchCmd; bool mSearchReverse; guint mSearchSelect; ApvlvPoses *mSearchResults; string mSearchStr; enum { NORMAL, FITWIDTH, FITHEIGHT, CUSTOM } mZoommode; double mZoomrate; bool mZoominit; int mRotatevalue; bool mAdjInchg; int mPagenum; int mSkip; double mPagex, mPagey; double mVrate, mHrate; int mLines, mChars; int mWidth, mHeight; GtkAdjustment *mVaj, *mHaj; // the main widget GtkWidget *mVbox; // the document scrolled window GtkWidget *mScrollwin; // if active bool mActive; // status bar ApvlvCoreStatus *mStatus; private: static gboolean apvlv_core_check_reload (gpointer); gchar *checkmd5 (); }; } #endif apvlv-0.1.1-Source/src/ApvlvUtil.hpp100644 1750 1750 6312 11521211167 16403 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvUtil.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_UTIL_H_ #define _APVLV_UTIL_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include #include #include #include using namespace std; namespace apvlv { // Global files extern string helppdf; extern string iniexam; extern string inifile; extern string icondir; extern string iconreg; extern string iconpdf; extern string sessionfile; #ifndef PATH_MAX #define PATH_MAX 4096 #endif #ifdef WIN32 #define PATH_SEP_C '\\' #define PATH_SEP_S "\\" #else #define PATH_SEP_C '/' #define PATH_SEP_S "/" #endif int apvlv_system (const char *); char *absolutepath (const char *path); bool filecpy (const char *dst, const char *src); #define CORE_NONE 0 #define CORE_DOC 1 #define CORE_CONTENT 2 #define CORE_DIR 3 GtkWidget *replace_widget (GtkWidget * owid, GtkWidget * nwid); // command type enum { CMD_NONE, CMD_MESSAGE, CMD_CMD }; // function return type typedef enum { MATCH, NEED_MORE, NO_MATCH, } returnType; // some windows macro #ifdef WIN32 #include #include #define usleep(x) Sleep((x) / 1000) #define __func__ __FUNCTION__ #define strcasecmp _strcmpi #ifndef S_ISDIR #define S_ISDIR(mode) (((mode) & 0170000) == (0040000)) #endif /* */ #endif gboolean walkdir (const char *, gboolean (*)(const char *, void *), void *); // log system #if defined DEBUG || defined _DEBUG #define debug(...) logv ("DEBUG", __FILE__, __LINE__, __func__, __VA_ARGS__) #define asst(s) do { \ if (!(s)) \ { \ debug ("(%s) is FALSE, exit", #s); \ exit (1); \ } \ } while (0) #else #define debug(...) #define asst(s) #endif #define errp(...) logv ("ERROR", __FILE__, __LINE__, __func__, __VA_ARGS__) void logv (const char *, const char *, int, const char *, const char *, ...); // char macro // because every unsigned char is < 256, so use this marco to stand for Ctrl+char, Shift+char #define CTRL(c) ((c) + 256) #define SHIFT(c) (CTRL(c) + 256) } #endif apvlv-0.1.1-Source/src/ApvlvDoc.cpp100644 1750 1750 142671 11521211167 16237 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvDoc.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvUtil.hpp" #include "ApvlvParams.hpp" #include "ApvlvInfo.hpp" #include "ApvlvView.hpp" #include "ApvlvDoc.hpp" #include #include #include #include #include #include #include #include namespace apvlv { static void invert_pixbuf (GdkPixbuf *); static GtkPrintSettings *settings = NULL; const int APVLV_DOC_CURSOR_WIDTH = 2; ApvlvDoc::ApvlvDoc (int w, int h, const char *zm, bool cache) { mCurrentCache1 = mCurrentCache2 = NULL; mReady = false; mAdjInchg = false; mAutoScrollPage = gParams->valueb ("autoscrollpage"); mAutoScrollDoc = gParams->valueb ("autoscrolldoc");; mContinuous = gParams->valueb ("continuous");; mZoominit = false; mLines = 50; mChars = 80; mProCmd = 0; mRotatevalue = 0; mFile = NULL; mSearchResults = NULL; mSearchStr = ""; GtkWidget *vbox, *ebox; if (mContinuous && gParams->valuei ("continuouspad") > 0) { vbox = gtk_vbox_new (FALSE, gParams->valuei ("continuouspad")); } else { vbox = gtk_vbox_new (FALSE, 0); } ebox = gtk_event_box_new (); gtk_container_add (GTK_CONTAINER (ebox), vbox); g_signal_connect (G_OBJECT (ebox), "button-press-event", G_CALLBACK (apvlv_doc_button_event), this); g_signal_connect (G_OBJECT (ebox), "motion-notify-event", G_CALLBACK (apvlv_doc_motion_event), this); gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (mScrollwin), ebox); mImage1 = gtk_image_new (); gtk_box_pack_start (GTK_BOX (vbox), mImage1, TRUE, TRUE, 0); if (mAutoScrollPage && mContinuous) { mImage2 = gtk_image_new (); gtk_box_pack_start (GTK_BOX (vbox), mImage2, TRUE, TRUE, 0); } g_signal_connect (G_OBJECT (mVaj), "value-changed", G_CALLBACK (apvlv_doc_on_mouse), this); mStatus = new ApvlvDocStatus (this); gtk_box_pack_start (GTK_BOX (mVbox), mScrollwin, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (mVbox), mStatus->widget (), FALSE, FALSE, 0); setsize (w, h); setzoom (zm); } ApvlvDoc::~ApvlvDoc () { if (mCurrentCache1) delete mCurrentCache1; if (mCurrentCache2) delete mCurrentCache2; savelastposition (filename ()); mPositions.clear (); if (mFile) { delete mFile; } delete mStatus; } void ApvlvDoc::blankarea (int x1, int y1, int x2, int y2, guchar * buffer, int width, int height) { // debug ("x1: %d, y1: %d, x2: %d, y2:%d", x1, y1, x2, y2); if (x2 > width) { x2 = width; } if (y2 > height) { y2 = height; } for (gint y = y1; y < y2; y++) { for (gint x = x1; x < x2; x++) { gint p = (gint) (y * width * 3 + (x * 3)); buffer[p + 0] = 0xff - buffer[p + 0]; buffer[p + 1] = 0xff - buffer[p + 1]; buffer[p + 2] = 0xff - buffer[p + 2]; } } } void ApvlvDoc::blankaction (double x, double y) { ApvlvDocCache *cache; ApvlvPos pos = { x, x, y, y }; if (x < 0) { x = 0; } if (y < 0) { y = 0; } cache = mCurrentCache1; if (x > cache->getwidth ()) { x = cache->getwidth (); } if (y > cache->getheight ()) { if (mCurrentCache2 != NULL) { cache = mCurrentCache2; } else { cache = NULL; } } if (cache == NULL) { return; } if (strcasecmp (gParams->values ("doubleclick"), "word") == 0) { ApvlvWord *word; word = cache->getword (x, cache == mCurrentCache2 ? y - mCurrentCache1->getheight () - gParams->valuei ("continuouspad") : y); if (word != NULL) { pos = word->pos; debug ("get word: [%s] x1:%f, x2:%f, y1:%f, y2:%f", word->word.c_str (), pos.x1, pos.x2, pos.y1, pos.y2); } } else if (strcasecmp (gParams->values ("doubleclick"), "line") == 0) { ApvlvLine *line; line = cache->getline (x, cache == mCurrentCache2 ? y - mCurrentCache1->getheight () - gParams->valuei ("continuouspad") : y); if (line != NULL) { pos = line->pos; } } else if (strcasecmp (gParams->values ("doubleclick"), "page") == 0) { pos.x1 = 0; pos.x2 = cache->getwidth (); pos.y1 = 0; pos.y2 = cache->getheight (); } else { return; } mInVisual = VISUAL_CTRL_V; mBlankx1 = pos.x1; mBlanky1 = pos.y1; blank (pos.x2, pos.y2); // yank (1); } void ApvlvDoc::blank (int bx, int by) { // debug ("bx: %d, by: %d", bx, by); ApvlvDocCache *cache = mCurrentCache1; gint rate = cache->getheight () / mLines; // get the right cache, 1 or 2 if (by + rate >= cache->getheight ()) { if (mCurrentCache2 == NULL) { by = cache->getheight () - rate; } else { cache = mCurrentCache2; rate = cache->getheight () / mLines; } } // fix the width and height value if (bx + APVLV_DOC_CURSOR_WIDTH >= cache->getwidth ()) { bx = cache->getwidth () - APVLV_DOC_CURSOR_WIDTH; } if (bx < 0) { bx = 0; } if (by < 0) { by = 0; } // remember the position mCurx = bx; mCury = by; guchar *buffer = cache->getdata (true); GdkPixbuf *pixbuf = cache->getbuf (true); if (buffer == NULL || pixbuf == NULL) { debug ("pixbuf data or structure error"); return; } mBlankx2 = bx; mBlanky2 = by; gint y1 = mBlanky1, y2 = mBlanky2; if (y1 > y2) { y1 = mBlanky2; y2 = mBlanky1; } gint x1 = mBlankx1, x2 = mBlankx2; if (x1 > x2) { x1 = mBlankx2; x2 = mBlankx1; } // fix the height value // corret to the cache's height // if the height > cache1, the minus it if (cache == mCurrentCache2) { by -= mCurrentCache1->getheight () - gParams->valuei ("continuouspad"); y1 -= mCurrentCache1->getheight () - gParams->valuei ("continuouspad"); y2 -= mCurrentCache1->getheight () - gParams->valuei ("continuouspad"); } if (by < 0) { by = 0; } if (y1 < 0) { y1 = 0; } if (y2 < 0) { y2 = 0; } if (mInVisual == VISUAL_V) { // debug (""); if (y1 + rate >= y2) { blankarea (x1, y1, x2 + APVLV_DOC_CURSOR_WIDTH, y1 == y2 ? y1 + rate : y2, buffer, cache->getwidth (), cache->getheight ()); } else if (y1 + rate * 2 >= y2) { blankarea (x1, y1, cache->getwidth (), y1 + rate, buffer, cache->getwidth (), cache->getheight ()); blankarea (0, y1 + rate, x2 + APVLV_DOC_CURSOR_WIDTH, y2, buffer, cache->getwidth (), cache->getheight ()); } else { blankarea (x1, y1, cache->getwidth (), y1 + rate, buffer, cache->getwidth (), cache->getheight ()); blankarea (0, y1 + rate, cache->getwidth (), y2 - rate, buffer, cache->getwidth (), cache->getheight ()); blankarea (0, y2 - rate, x2 + APVLV_DOC_CURSOR_WIDTH, y2, buffer, cache->getwidth (), cache->getheight ()); } } else if (mInVisual == VISUAL_CTRL_V) { // debug (""); blankarea (x1, y1, x1 + APVLV_DOC_CURSOR_WIDTH > x2 ? x1 + APVLV_DOC_CURSOR_WIDTH : x2, y1 + rate > y2 ? y1 + rate : y2, buffer, cache->getwidth (), cache->getheight ()); } else { // debug (""); blankarea (bx, by, bx + APVLV_DOC_CURSOR_WIDTH, by + rate, buffer, cache->getwidth (), cache->getheight ()); } // reset the pixbuf to image container if (cache == mCurrentCache1) { if (mCurrentCache2 != NULL) { mCurrentCache2->getdata (true); GdkPixbuf *p = mCurrentCache2->getbuf (true); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage2), p); } gtk_image_set_from_pixbuf (GTK_IMAGE (mImage1), pixbuf); } else { mCurrentCache1->getdata (true); GdkPixbuf *p = mCurrentCache1->getbuf (true); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage1), p); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage2), pixbuf); } } void ApvlvDoc::togglevisual (int key) { if (gParams->valueb ("visualmode") == false) { return; } if (mInVisual == VISUAL_NONE) { mBlankx1 = mCurx; mBlanky1 = mCury; } int type = key == 'v' ? VISUAL_V : VISUAL_CTRL_V; if (mInVisual == type) { mInVisual = VISUAL_NONE; } else { mInVisual = type; } blank (mCurx, mCury); } int ApvlvDoc::yank (int times) { char *txt1 = NULL, *txt2 = NULL, *txt3 = NULL; gint y1 = mBlanky1, y2 = mBlanky2; if (y1 > y2) { y1 = mBlanky2; y2 = mBlanky1; } gint x1 = mBlankx1, x2 = mBlankx2; if (x1 > x2) { x1 = mBlankx2; x2 = mBlankx1; } if (y1 == y2 || mInVisual == VISUAL_CTRL_V) { mFile->pagetext (mPagenum, x1, y1, x2 + APVLV_DOC_CURSOR_WIDTH, y2 + mVrate, &txt1); } else { mFile->pagetext (mPagenum, x1, y1, (int) mCurrentCache1->getwidth (), (int) (y1 + mVrate), &txt1); mFile->pagetext (mPagenum, 0, y1 + mVrate, (int) mCurrentCache1->getwidth (), y2, &txt2); mFile->pagetext (mPagenum, 0, y2, x2 + APVLV_DOC_CURSOR_WIDTH, y2 + mVrate, &txt3); } GtkClipboard *cb = gtk_clipboard_get (NULL); string text = ""; if (txt1 != NULL) { text += txt1; g_free (txt1); } if (txt2 != NULL) { text += txt2; g_free (txt2); } if (txt3 != NULL) { text += txt3; g_free (txt3); } gtk_clipboard_set_text (cb, text.c_str (), text.length ()); return 0; } returnType ApvlvDoc::subprocess (int ct, guint key) { guint procmd = mProCmd; mProCmd = 0; switch (procmd) { case 'm': markposition (key); break; case '\'': jump (key); break; case 'z': if (key == 'i') { char temp[0x10]; g_snprintf (temp, sizeof temp, "%f", mZoomrate * 1.1); setzoom (temp); } else if (key == 'o') { char temp[0x10]; g_snprintf (temp, sizeof temp, "%f", mZoomrate / 1.1); setzoom (temp); } else if (key == 'h') { setzoom ("fitheight"); } else if (key == 'w') { setzoom ("fitwidth"); } break; default: return NO_MATCH; break; } return MATCH; } returnType ApvlvDoc::process (int has, int ct, guint key) { if (mProCmd != 0) { return subprocess (ct, key); } if (!has) { ct = 1; } switch (key) { case GDK_Page_Down: case CTRL ('f'): nextpage (ct); break; case GDK_Page_Up: case CTRL ('b'): prepage (ct); break; case CTRL ('d'): halfnextpage (ct); break; case CTRL ('u'): halfprepage (ct); break; case ':': case '/': case '?': gView->promptcommand (key); return NEED_MORE; case 'H': scrollto (0.0); blank (0, 0); break; case 'M': scrollto (0.5); blank (0, mVaj->upper / 2); break; case 'L': scrollto (1.0); blank (0, mVaj->upper); break; case '0': scrollleft (mChars); break; case '$': scrollright (mChars); break; case CTRL ('p'): case GDK_Up: case 'k': scrollup (ct); break; case CTRL ('n'): case CTRL ('j'): case GDK_Down: case 'j': scrolldown (ct); break; case GDK_BackSpace: case GDK_Left: case CTRL ('h'): case 'h': scrollleft (ct); break; case GDK_space: case GDK_Right: case CTRL ('l'): case 'l': scrollright (ct); break; case 'R': reload (); break; case 'o': gView->open (); break; case 'O': gView->opendir (); break; case CTRL (']'): gotolink (ct); break; case CTRL ('t'): returnlink (ct); break; case 'r': rotate (ct); break; case 'G': markposition ('\''); if (has) { ct += mSkip; showpage (ct - 1); } else { showpage (-1); } break; case 'm': case '\'': case 'z': mProCmd = key; return NEED_MORE; break; case 'n': if (mSearchCmd == SEARCH) { markposition ('\''); search (""); } else if (mSearchCmd == BACKSEARCH) { markposition ('\''); search ("", true); } else { } break; case 'N': if (mSearchCmd == SEARCH) { markposition ('\''); search ("", true); } else if (mSearchCmd == BACKSEARCH) { markposition ('\''); search (""); } else { } break; case CTRL ('v'): case 'v': togglevisual (key); break; case ('y'): yank (ct); mInVisual = VISUAL_NONE; blank (mCurx, mCury); break; case ('s'): setskip (ct); break; default: return NO_MATCH; break; } return MATCH; } ApvlvDoc *ApvlvDoc::copy () { char rate[16]; g_snprintf (rate, sizeof rate, "%f", mZoomrate); ApvlvDoc *ndoc = new ApvlvDoc (mWidth, mHeight, rate, usecache ()); ndoc->loadfile (mFilestr, false); ndoc->showpage (mPagenum, scrollrate ()); return ndoc; } void ApvlvDoc::setzoom (const char *z) { if (z != NULL) { if (strcasecmp (z, "normal") == 0) { mZoommode = NORMAL; mZoomrate = 1.2; } if (strcasecmp (z, "fitwidth") == 0) { mZoommode = FITWIDTH; } if (strcasecmp (z, "fitheight") == 0) { mZoommode = FITHEIGHT; } else { double d = atof (z); if (d > 0) { mZoommode = CUSTOM; mZoomrate = d; } } } if (mFile != NULL) { mFile->pagesize (0, mRotatevalue, &mPagex, &mPagey); if (mZoommode == FITWIDTH) { mZoomrate = ((double) (mWidth - 26)) / mPagex; } else if (mZoommode == FITHEIGHT) { mZoomrate = ((double) (mHeight - 26)) / mPagey; } refresh (); } } bool ApvlvDoc::savelastposition (const char *filename) { if (filename == NULL || helppdf == filename || gParams->valueb ("noinfo")) { return false; } bool ret = gInfo->file (mPagenum, scrollrate (), filename, mSkip); return ret; } bool ApvlvDoc::loadlastposition (const char *filename) { if (filename == NULL || helppdf == filename || gParams->valueb ("noinfo")) { showpage (0); return false; } if (gParams->valueb ("noinfo")) { showpage (0); return false; } bool ret = false; infofile *fp = gInfo->file (filename); // correctly check mScrollvalue = fp->rate; showpage (fp->page); setskip (fp->skip); // Warning // I can't think a better way to scroll correctly when // the page is not be displayed correctly g_timeout_add (50, apvlv_doc_first_scroll_cb, this); return ret; } bool ApvlvDoc::reload () { savelastposition (filename ()); return loadfile (mFilestr, false); } bool ApvlvDoc::loadfile (string & filename, bool check) { return loadfile (filename.c_str (), check); } gint ApvlvDoc::pagenumber () { if (mContinuous && mCurrentCache2 != NULL) { if (scrollrate () > 0.5) { return mCurrentCache2->getpagenum () + 1; } else { return mCurrentCache1->getpagenum () + 1; } } else { return mPagenum + 1; } } bool ApvlvDoc::usecache () { return false; } void ApvlvDoc::usecache (bool use) { if (use) { gView->errormessage ("No pthread, can't support cache!!!"); gView->infomessage ("If you really have pthread, please recomplie the apvlv and try again."); } } bool ApvlvDoc::loadfile (const char *filename, bool check) { if (check) { if (strcmp (filename, mFilestr.c_str ()) == 0) { return false; } } if (mFile) { delete mFile; mFile = NULL; } mReady = false; mFile = ApvlvFile::newfile (filename); debug ("mFile = %p", mFile); if (mFile != NULL) { mFilestr = filename; if (mFile->pagesum () <= 1) { debug ("pagesum () = %d", mFile->pagesum ()); mContinuous = false; mAutoScrollDoc = false; mAutoScrollPage = false; } debug ("pagesum () = %d", mFile->pagesum ()); if (mCurrentCache1 != NULL) { delete mCurrentCache1; mCurrentCache1 = NULL; } mCurrentCache1 = new ApvlvDocCache (mFile); if (mCurrentCache2 != NULL) { delete mCurrentCache2; mCurrentCache2 = NULL; } if (mContinuous == true) { mCurrentCache2 = new ApvlvDocCache (mFile); } loadlastposition (filename); mStatus->show (); setactive (true); mReady = true; mSearchStr = ""; if (mSearchResults != NULL) { delete mSearchResults; mSearchResults = NULL; } mInVisual = VISUAL_NONE; } return mFile == NULL ? false : true; } int ApvlvDoc::convertindex (int p) { if (mFile != NULL) { int c = mFile->pagesum (); if (p >= 0 && p < c) { return p; } else if (p >= c && mAutoScrollDoc) { return p % c; } else if (p < 0 && mAutoScrollDoc) { return c + p; } else { return -1; } } return -1; } void ApvlvDoc::markposition (const char s) { ApvlvDocPosition adp = { mPagenum, scrollrate () }; mPositions[s] = adp; } void ApvlvDoc::jump (const char s) { ApvlvDocPositionMap::iterator it; it = mPositions.find (s); if (it != mPositions.end ()) { ApvlvDocPosition adp = it->second; markposition ('\''); showpage (adp.pagenum, adp.scrollrate); } } void ApvlvDoc::showpage (int p, double s) { int rp = convertindex (p); if (rp < 0) return; debug ("show page: %d", rp); mAdjInchg = true; if (mAutoScrollPage && mContinuous && !mAutoScrollDoc) { int rp2 = convertindex (p + 1); if (rp2 < 0) { if (rp == mPagenum + 1) { return; } else { rp--; } } } mPagenum = rp; if (mZoominit == false) { mZoominit = true; setzoom (NULL); debug ("zoom rate: %f", mZoomrate); } refresh (); scrollto (s); } void ApvlvDoc::nextpage (int times) { showpage (mPagenum + times); } void ApvlvDoc::prepage (int times) { showpage (mPagenum - times); } void ApvlvDoc::refresh () { if (mFile == NULL) return; mCurrentCache1->set (mPagenum, mZoomrate, mRotatevalue, false); GdkPixbuf *buf = mCurrentCache1->getbuf (true); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage1), buf); if (mAutoScrollPage && mContinuous) { mCurrentCache2->set (convertindex (mPagenum + 1), mZoomrate, mRotatevalue, false); buf = mCurrentCache2->getbuf (true); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage2), buf); } mStatus->show (); } void ApvlvDoc::halfnextpage (int times) { double sr = scrollrate (); int rtimes = times / 2; if (times % 2 != 0) { if (sr > 0.5) { sr = 0; rtimes += 1; } else { sr = 1; } } showpage (mPagenum + rtimes, sr); } void ApvlvDoc::halfprepage (int times) { double sr = scrollrate (); int rtimes = times / 2; if (times % 2 != 0) { if (sr < 0.5) { sr = 1; rtimes += 1; } else { sr = 0; } } showpage (mPagenum - rtimes, sr); } void ApvlvDoc::markselection () { debug ("mSelect: %d.", mSearchSelect); debug ("zoomrate: %f", mZoomrate); ApvlvPos rect = (*mSearchResults)[mSearchSelect]; // Caculate the correct position //debug ("pagex: %f, pagey: %f, x1: %f, y1: %f, x2: %f, y2: %f", mPagex, mPagey, rect->x1, rect->y1, rect->x2, rect->y2); gint x1 = (gint) ((rect.x1) * mZoomrate); gint x2 = (gint) ((rect.x2) * mZoomrate); gint y1 = (gint) ((mPagey - rect.y2) * mZoomrate); gint y2 = (gint) ((mPagey - rect.y1) * mZoomrate); debug ("x1: %d, y1: %d, x2: %d, y2: %d", x1, y1, x2, y2); // make the selection at the page center gdouble val = ((y1 + y2) - mVaj->page_size) / 2; debug ("upper: %f, lower: %f, page_size: %f, val: %f", mVaj->upper, mVaj->lower, mVaj->page_size, val); if (val + mVaj->page_size > mVaj->upper - mVaj->lower - 5) { debug ("set value: %f", mVaj->upper - mVaj->lower - mVaj->page_size - 5); gtk_adjustment_set_value (mVaj, mVaj->upper - mVaj->lower - mVaj->page_size - 5); /* just for avoid the auto scroll page */ } else if (val > 5) { debug ("set value: %f", val); gtk_adjustment_set_value (mVaj, val); } else { debug ("set value: %f", mVaj->lower + 5); gtk_adjustment_set_value (mVaj, mVaj->lower + 5); /* avoid auto scroll page */ } val = ((x1 + x2) - mHaj->page_size) / 2; if (val + mHaj->page_size > mHaj->upper) { gtk_adjustment_set_value (mHaj, mHaj->upper); } else if (val > 0) { gtk_adjustment_set_value (mHaj, val); } else { gtk_adjustment_set_value (mHaj, mHaj->lower); } mCurrentCache1->set (mPagenum, mZoomrate, mRotatevalue); guchar *pagedata = mCurrentCache1->getdata (true); GdkPixbuf *pixbuf = mCurrentCache1->getbuf (true); mFile->pageselectsearch (mPagenum, mCurrentCache1->getwidth (), mCurrentCache1->getheight (), mZoomrate, mRotatevalue, pixbuf, (char *) pagedata, mSearchSelect, mSearchResults); gtk_image_set_from_pixbuf (GTK_IMAGE (mImage1), pixbuf); debug ("helight num: %d", mPagenum); } bool ApvlvDoc::continuous () { return mContinuous; } void ApvlvDoc::scrollup (int times) { if (!mReady) return; if (gParams->valueb ("visualmode") == false) { ApvlvCore::scrollup (times); return; } gdouble sub = mVaj->upper - mVaj->lower; mVrate = sub / mLines; gint opage = mPagenum, npage = mPagenum; gint ny1 = mCury - mVrate * times; if (ny1 < mVaj->value) { ApvlvCore::scrollup (times); npage = mPagenum; } if (npage == opage) { blank (mCurx, ny1); } else { if (gParams->valueb ("continuous") == false) { blank (mCurx, mScrollvalue * mCurrentCache1->getheight ()); } else { blank (mCurx, mVaj->upper / 2); } } } void ApvlvDoc::scrolldown (int times) { if (!mReady) return; if (gParams->valueb ("visualmode") == false) { ApvlvCore::scrolldown (times); return; } gdouble sub = mVaj->upper - mVaj->lower; mVrate = sub / mLines; gint opage = mPagenum, npage = mPagenum; gint ny1 = mCury + mVrate * times; if (ny1 - mVaj->value >= mVaj->page_size) { ApvlvCore::scrolldown (times); npage = mPagenum; } if (npage == opage) { blank (mCurx, ny1); } else { if (gParams->valueb ("continuous") == false) { blank (mCurx, mScrollvalue * mCurrentCache1->getheight ()); } else { blank (mCurx, mVaj->upper / 2); } } } void ApvlvDoc::scrollleft (int times) { if (!mReady) return; if (gParams->valueb ("visualmode") == false) { ApvlvCore::scrollleft (times); return; } gdouble sub = mHaj->upper - mHaj->lower; mHrate = sub / mChars; gint nx1 = mCurx - mHrate * times; if (nx1 < mHaj->upper - mHaj->page_size) { ApvlvCore::scrollleft (times); } blank (nx1, mCury); } void ApvlvDoc::scrollright (int times) { if (!mReady) return; if (gParams->valueb ("visualmode") == false) { ApvlvCore::scrollright (times); return; } gdouble sub = mHaj->upper - mHaj->lower; mHrate = sub / mChars; gint nx1 = mCurx + mHrate * times; if (nx1 > mHaj->page_size) { ApvlvCore::scrollright (times); } blank (nx1, mCury); } bool ApvlvDoc::needsearch (const char *str, bool reverse) { if (mFile == NULL) return false; // search a different string if (strlen (str) > 0 && strcmp (str, mSearchStr.c_str ()) != 0) { debug ("different string."); mSearchSelect = 0; mSearchStr = str; return true; } else if (mSearchResults == NULL) { debug ("no result."); mSearchSelect = 0; return true; } // same string, but need to search next page else if ((mSearchPagenum != mPagenum) || ((mSearchReverse == reverse) && mSearchSelect == mSearchResults->size () - 1) || ((mSearchReverse != reverse) && mSearchSelect == 0)) { debug ("same, but need next string: S: %d, s: %d, sel: %d, max: %d.", mSearchReverse, reverse, mSearchSelect, mSearchResults->size ()); mSearchSelect = 0; return true; } // same string, not need search, but has zoomed else { debug ("same, not need next string. sel: %d, max: %u", mSearchSelect, mSearchResults->size ()); if (mSearchReverse == reverse) { mSearchSelect++; } else { mSearchSelect--; } markselection (); return false; } } bool ApvlvDoc::search (const char *str, bool reverse) { if (*str == '\0' && mSearchStr == "") { return false; } if (*str != '\0') { mSearchCmd = reverse ? BACKSEARCH : SEARCH; } if (!needsearch (str, reverse)) { return true; } if (mSearchResults != NULL) { delete mSearchResults; mSearchResults = NULL; } bool wrap = gParams->valueb ("wrapscan"); int i = mPagenum; int sum = mFile->pagesum (), from = i; bool search = false; while (1) { if (*str != 0 || search) { mSearchResults = mFile->pagesearch ((i + sum) % sum, mSearchStr.c_str (), reverse); mSearchReverse = reverse; if (mSearchResults != NULL) { showpage ((i + sum) % sum, 0.5); mSearchPagenum = mPagenum; markselection (); return true; } } search = true; if (!reverse && i < (wrap ? (from + sum) : (sum - 1))) { // debug ("wrap: %d, i++:", wrap, i, i + 1); i++; } else if (reverse && i > (wrap ? (from - sum) : 0)) { debug ("wrap: %d, i--:", wrap, i, i - 1); i--; } else { gView->errormessage ("can't find word: '%s'", mSearchStr.c_str ()); return false; } } } bool ApvlvDoc::totext (const char *file) { if (mFile == NULL) return false; char *txt; bool ret = mFile->pagetext (mPagenum, 0, 0, mCurrentCache1->getwidth (), mCurrentCache1->getheight (), &txt); if (ret == true) { g_file_set_contents (file, txt, -1, NULL); return true; } return false; } void ApvlvDoc::setactive (bool act) { mStatus->active (act); mActive = act; } bool ApvlvDoc::rotate (int ct) { // just hack if (ct == 1) ct = 90; if (ct % 90 != 0) { gView->errormessage ("Not a 90 times value: %d", ct); return false; } mRotatevalue += ct; while (mRotatevalue < 0) { mRotatevalue += 360; } while (mRotatevalue > 360) { mRotatevalue -= 360; } refresh (); return true; } void ApvlvDoc::gotolink (int ct) { ApvlvLinks *links1 = mCurrentCache1->getlinks (); ApvlvLinks *links2 = mCurrentCache2 ? mCurrentCache2->getlinks () : NULL; int siz = links1 ? links1->size () : 0; siz += links2 ? links2->size () : 0; ct--; if (ct >= 0 && ct < siz) { markposition ('\''); ApvlvDocPosition p = { mPagenum, scrollrate () }; mLinkPositions.push_back (p); if (links1 == NULL) { showpage ((*links2)[ct].mPage); } else { if (ct < (int) links1->size ()) { showpage ((*links1)[ct].mPage); } else { showpage ((*links2)[ct - links1->size ()].mPage); } } } } void ApvlvDoc::returnlink (int ct) { debug ("Ctrl-t %d", ct); if (ct <= (int) mLinkPositions.size () && ct > 0) { markposition ('\''); ApvlvDocPosition p = { 0, 0 }; while (ct-- > 0) { p = mLinkPositions[mLinkPositions.size () - 1]; mLinkPositions.pop_back (); } showpage (p.pagenum, p.scrollrate); } } bool ApvlvDoc::print (int ct) { #ifdef WIN32 return false; #else bool ret = false; GtkPrintOperation *print = gtk_print_operation_new (); gtk_print_operation_set_allow_async (print, TRUE); gtk_print_operation_set_show_progress (print, TRUE); PrintData *data = new PrintData; data->file = mFile; data->frmpn = mPagenum; data->endpn = mPagenum + (ct > 0 ? ct : 1) - 1; if ((int) data->endpn >= mFile->pagesum ()) { data->endpn = mFile->pagesum () - 1; } //If nothing is specified, print all pages if (ct == -1) { data->frmpn = 0; data->endpn = mFile->pagesum () - 1; //revert to +ve value, since I don't know if ct is assumed to be +ve anywhere ct = mFile->pagesum (); } g_signal_connect (G_OBJECT (print), "begin-print", G_CALLBACK (begin_print), data); g_signal_connect (G_OBJECT (print), "draw-page", G_CALLBACK (draw_page), data); g_signal_connect (G_OBJECT (print), "end-print", G_CALLBACK (end_print), data); if (settings != NULL) { gtk_print_operation_set_print_settings (print, settings); } int r = gtk_print_operation_run (print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW (gView->widget ()), NULL); if (r == GTK_PRINT_OPERATION_RESULT_APPLY) { if (settings != NULL) { g_object_unref (settings); } settings = gtk_print_operation_get_print_settings (print); ret = true; } g_object_unref (print); return ret; #endif } void ApvlvDoc::apvlv_doc_on_mouse (GtkAdjustment * adj, ApvlvDoc * doc) { if (doc->mAdjInchg) { doc->mAdjInchg = false; return; } if (adj->upper - adj->lower == adj->page_size + adj->value) { doc->scrolldown (1); } else if (adj->value == 0) { doc->scrollup (1); } } gboolean ApvlvDoc::apvlv_doc_first_scroll_cb (gpointer data) { ApvlvDoc *doc = (ApvlvDoc *) data; gboolean retry = doc->scrollto (doc->mScrollvalue) == TRUE ? FALSE : TRUE; if (!retry) { doc->blank (0, doc->mScrollvalue * (doc->mVaj->upper - doc->mVaj->lower - doc->mVaj->page_size)); } return retry; } gboolean ApvlvDoc::apvlv_doc_first_copy_cb (gpointer data) { ApvlvDoc *doc = (ApvlvDoc *) data; doc->loadfile (doc->mFilestr, false); return FALSE; } #ifndef WIN32 void ApvlvDoc::begin_print (GtkPrintOperation * operation, GtkPrintContext * context, PrintData * data) { gtk_print_operation_set_n_pages (operation, data->endpn - data->frmpn + 1); } void ApvlvDoc::draw_page (GtkPrintOperation * operation, GtkPrintContext * context, gint page_nr, PrintData * data) { cairo_t *cr = gtk_print_context_get_cairo_context (context); data->file->pageprint (data->frmpn + page_nr, cr); PangoLayout *layout = gtk_print_context_create_pango_layout (context); pango_cairo_show_layout (cr, layout); g_object_unref (layout); } void ApvlvDoc::end_print (GtkPrintOperation * operation, GtkPrintContext * context, PrintData * data) { delete data; } #endif void ApvlvDoc::apvlv_doc_button_event (GtkEventBox * box, GdkEventButton * button, ApvlvDoc * doc) { if (button->button == 1) { if (button->type == GDK_BUTTON_PRESS) { // this is a manual method to test double click // I think, a normal user double click will in 500 millseconds if (button->time - doc->mLastpress < 500) { doc->mInVisual = VISUAL_NONE; double rx, ry; doc->eventpos (button->x, button->y, &rx, &ry); doc->blankaction (rx, ry); } else { doc->mBlankx1 = button->x; doc->mBlanky1 = button->y; doc->mInVisual = VISUAL_NONE; double rx, ry; doc->eventpos (button->x, button->y, &rx, &ry); doc->blank (rx, ry); } doc->mLastpress = button->time; } } else if (button->button == 3) { if (doc->mInVisual == VISUAL_NONE) { return; } doc->mInVisual = VISUAL_NONE; GtkWidget *menu, *item; menu = gtk_menu_new (); gtk_menu_attach_to_widget (GTK_MENU (menu), GTK_WIDGET (box), NULL); item = gtk_image_menu_item_new_with_label ("Copy to Clipboard"); gtk_menu_shell_append (GTK_MENU_SHELL (menu), item); gtk_widget_show (item); g_signal_connect (item, "activate", G_CALLBACK (apvlv_doc_copytoclipboard_cb), doc); gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL, 0, 0); } } void ApvlvDoc::apvlv_doc_copytoclipboard_cb (GtkMenuItem * item, ApvlvDoc * doc) { doc->yank (1); doc->mInVisual = VISUAL_NONE; doc->blank (doc->mCurx, doc->mCury); } void ApvlvDoc::apvlv_doc_motion_event (GtkWidget * box, GdkEventMotion * motion, ApvlvDoc * doc) { doc->mInVisual = VISUAL_V; double rx, ry; doc->eventpos (motion->x, motion->y, &rx, &ry); doc->blank (rx, ry); } void ApvlvDoc::eventpos (double x, double y, double *rx, double *ry) { int dw, dh; if (rx != NULL) { dw = mPagex * mZoomrate - mScrollwin->allocation.width; dw = dw >> 1; if (dw >= 0) { dw = 0; } *rx = x + dw; } if (ry != NULL) { dh = mPagey * mZoomrate - mScrollwin->allocation.height; dh = dh >> 1; if (dh >= 0) { dh = 0; } *ry = y + dh; } } ApvlvDocCache::ApvlvDocCache (ApvlvFile * file) { mFile = file; mPagenum = -1; mLines = NULL; mData = NULL; mSize = 0; mBuf = NULL; mLinks = NULL; } void ApvlvDocCache::set (guint p, double zm, guint rot, bool delay) { mPagenum = p; mZoom = zm; mRotate = rot; if (mLines != NULL) { delete mLines; mLines = NULL; } if (mData != NULL) { delete[]mData; mData = NULL; } if (mBuf != NULL) { g_object_unref (mBuf); mBuf = NULL; } if (mLinks != NULL) { delete mLinks; mLinks = NULL; } mInverted = gParams->valueb ("inverted"); load (this); } void ApvlvDocCache::load (ApvlvDocCache * ac) { int c = ac->mFile->pagesum (); if (ac->mPagenum < 0 || ac->mPagenum >= c) { debug ("no this page: %d", ac->mPagenum); return; } double tpagex, tpagey; ac->mFile->pagesize (ac->mPagenum, ac->mRotate, &tpagex, &tpagey); ac->mWidth = MAX ((tpagex * ac->mZoom + 0.5), 1); ac->mHeight = MAX ((tpagey * ac->mZoom + 0.5), 1); // this is very import to get the double times size data // the 2ed chunk data will be for output ac->mSize = ac->mWidth * ac->mHeight * 3; guchar *dat = new guchar[2 * ac->mSize]; GdkPixbuf *bu = gdk_pixbuf_new_from_data (dat, GDK_COLORSPACE_RGB, FALSE, 8, ac->mWidth, ac->mHeight, 3 * ac->mWidth, NULL, NULL); debug ("ac->mFile: %p", ac->mFile); ac->mFile->render (ac->mPagenum, ac->mWidth, ac->mHeight, ac->mZoom, ac->mRotate, bu, (char *) dat); if (ac->mInverted) { invert_pixbuf (bu); } // backup the pixbuf data memcpy (dat + ac->mSize, dat, ac->mSize); if (ac->mLinks) { delete ac->mLinks; } ac->mLinks = ac->mFile->getlinks (ac->mPagenum); debug ("has mLinkMappings: %p", ac->mLinks); ac->mData = dat; ac->mBuf = bu; ac->preparelines (0, 0, tpagex, tpagey); } ApvlvDocCache::~ApvlvDocCache () { if (mLinks) { delete mLinks; } if (mLines != NULL) { delete mLines; } if (mData != NULL) { delete[]mData; } if (mBuf != NULL) { g_object_unref (mBuf); } } guint ApvlvDocCache::getpagenum () { return mPagenum; } /* * get the cache data * @param: wait, if not wait, not wait the buffer be prepared * @return: the buffer * */ guchar *ApvlvDocCache::getdata (bool wait) { memcpy (mData, mData + mSize, mSize); return mData; } /* * get the cache GdkPixbuf * @param: wait, if not wait, not wait the pixbuf be prepared * @return: the buffer * */ GdkPixbuf *ApvlvDocCache::getbuf (bool wait) { return mBuf; } double ApvlvDocCache::getwidth () { return mWidth; } double ApvlvDocCache::getheight () { return mHeight; } ApvlvLinks *ApvlvDocCache::getlinks () { return mLinks; } bool ApvlvDocCache::canselect () { return mLines != NULL ? true : false; } ApvlvWord *ApvlvDocCache::getword (int x, int y) { ApvlvLine *line; line = getline (x, y); if (line != NULL) { vector < ApvlvWord >::iterator itr; for (itr = line->mWords.begin (); itr != line->mWords.end (); itr++) { debug ("itr: %f,%f", itr->pos.y1, itr->pos.y2); if (x >= itr->pos.x1 && x <= itr->pos.x2) { return &(*itr); } } } return NULL; } ApvlvLine *ApvlvDocCache::getline (double x, double y) { debug ("getline: %f", y); if (mLines == NULL) { return NULL; } vector < ApvlvLine >::iterator itr; for (itr = mLines->begin (); itr != mLines->end (); itr++) { debug ("itr: %f,%f", itr->pos.y1, itr->pos.y2); if (y >= itr->pos.y2 && y <= itr->pos.y1) { return &(*itr); } } return NULL; } void ApvlvDocCache::preparelines (double x1, double y1, double x2, double y2) { if (strcmp (gParams->values ("doubleclick"), "page") == 0 || strcmp (gParams->values ("doubleclick"), "none") == 0) { return; } gchar *content = NULL; mFile->pagetext (mPagenum, x1, y1, x2, y2, &content); if (content != NULL) { ApvlvPoses *results; string word; mLines = new vector < ApvlvLine >; ApvlvPos lastpos = { 0, 0, 0, 0 }; if (strcmp (gParams->values ("doubleclick"), "word") == 0) { stringstream ss (content); while (!ss.eof ()) { ss >> word; results = mFile->pagesearch (mPagenum, word.c_str ()); if (results != NULL) { lastpos = prepare_add (lastpos, results, word.c_str ()); delete results; } } } else { gchar **v, *p; int i; v = g_strsplit (content, "\n", -1); if (v != NULL) { for (i = 0; v[i] != NULL; ++i) { p = v[i]; while (*p != '\0' && isspace (*p)) { p++; } if (*p == '\0') { continue; } debug ("search [%s]", p); results = mFile->pagesearch (mPagenum, p); if (results != NULL) { lastpos = prepare_add (lastpos, results, p); delete results; } } g_strfreev (v); } } vector < ApvlvLine >::iterator it; for (it = mLines->begin (); it != mLines->end (); it++) { // debug ("line: %f, %f, %f, %f", it->pos.x1, it->pos.y1, // it->pos.x2, it->pos.y2); vector < ApvlvWord >::iterator wit; for (wit = it->mWords.begin (); wit != it->mWords.end (); wit++) { // debug ("word: %f, %f, %f, %f: %s", wit->pos.x1, wit->pos.y1, // wit->pos.x2, wit->pos.y2, wit->word.c_str ()); } } g_free (content); } } ApvlvPos ApvlvDocCache::prepare_add (ApvlvPos & lastpos, ApvlvPoses * results, const char *word) { ApvlvPoses::iterator itr; for (itr = results->begin (); itr != results->end (); itr++) { itr->x1 *= mZoom; itr->x2 *= mZoom; itr->y1 = mHeight - itr->y1 * mZoom; itr->y2 = mHeight - itr->y2 * mZoom; if ((lastpos.y2 < itr->y2) || (lastpos.y2 - itr->y2 < 0.0001 && lastpos.x2 < itr->x2)) { debug ("[%s] x1:%f, x2:%f, y1:%f, y2:%f", word, itr->x1, itr->x2, itr->y1, itr->y2); break; } } if (itr == results->end ()) { itr = results->begin (); } // debug ("itr: %f, %f, %f, %f", itr->x1, itr->y1, itr->x2, itr->y2); vector < ApvlvLine >::iterator litr; for (litr = mLines->begin (); litr != mLines->end (); litr++) { // debug ("litr: %f, %f", litr->pos.y1, litr->pos.y2); if (fabs (itr->y1 - litr->pos.y1) < 0.0001 && fabs (itr->y2 - litr->pos.y2) < 0.0001) { break; } } ApvlvWord aword = { *itr, word }; if (litr != mLines->end ()) { litr->mWords.push_back (aword); if (itr->x1 < litr->pos.x1) { litr->pos.x1 = itr->x1; } if (itr->x2 > litr->pos.x2) { litr->pos.x2 = itr->x2; } } else { ApvlvLine line; line.pos = *itr; line.mWords.push_back (aword); mLines->push_back (line); } return *itr; } ApvlvDocStatus::ApvlvDocStatus (ApvlvDoc * doc) { mDoc = doc; for (int i = 0; i < AD_STATUS_SIZE; ++i) { mStlab[i] = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (mHbox), mStlab[i], FALSE, FALSE, 0); } } ApvlvDocStatus::~ApvlvDocStatus () { } void ApvlvDocStatus::active (bool act) { for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_widget_modify_fg (mStlab[i], (act) ? GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE, NULL); } } void ApvlvDocStatus::setsize (int w, int h) { int sw[AD_STATUS_SIZE]; sw[0] = w >> 1; sw[1] = sw[0] >> 1; sw[2] = sw[1] >> 1; sw[3] = sw[1] >> 1; for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_widget_set_usize (mStlab[i], sw[i], h); } } void ApvlvDocStatus::show () { if (mDoc->filename ()) { gint pn = mDoc->pagenumber (); char temp[AD_STATUS_SIZE][256]; gchar *bn; bn = g_path_get_basename (mDoc->filename ()); g_snprintf (temp[0], sizeof temp[0], "%s", bn); g_snprintf (temp[1], sizeof temp[1], "%d/%d", pn, mDoc->file ()->pagesum ()); g_snprintf (temp[2], sizeof temp[2], "%d%%", (int) (mDoc->zoomvalue () * 100)); g_snprintf (temp[3], sizeof temp[3], "%d%%", (int) (mDoc->scrollrate () * 100)); for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_label_set_text (GTK_LABEL (mStlab[i]), temp[i]); } g_free (bn); } } static void invert_pixbuf (GdkPixbuf * pixbuf) { guchar *data, *p; guint width, height, x, y, rowstride, n_channels; n_channels = gdk_pixbuf_get_n_channels (pixbuf); g_assert (gdk_pixbuf_get_colorspace (pixbuf) == GDK_COLORSPACE_RGB); g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8); /* First grab a pointer to the raw pixel data. */ data = gdk_pixbuf_get_pixels (pixbuf); /* Find the number of bytes per row (could be padded). */ rowstride = gdk_pixbuf_get_rowstride (pixbuf); width = gdk_pixbuf_get_width (pixbuf); height = gdk_pixbuf_get_height (pixbuf); for (x = 0; x < width; x++) { for (y = 0; y < height; y++) { /* Calculate pixel's offset into the data array. */ p = data + x * n_channels + y * rowstride; /* Change the RGB values */ p[0] = 255 - p[0]; p[1] = 255 - p[1]; p[2] = 255 - p[2]; } } } } apvlv-0.1.1-Source/src/ApvlvView.cpp100644 1750 1750 102111 11521211167 16425 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvView.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvParams.hpp" #include "ApvlvInfo.hpp" #include "ApvlvDir.hpp" #include "ApvlvCmds.hpp" #include "ApvlvView.hpp" #include #include #include #include #include #include #include #include #include namespace apvlv { ApvlvView *gView = NULL; const int ApvlvView::APVLV_MENU_HEIGHT = 30; const int ApvlvView::APVLV_CMD_BAR_HEIGHT = 20; const int ApvlvView::APVLV_TABS_HEIGHT = 36; ApvlvView::ApvlvView (const char *filename):mCurrTabPos (-1) { mProCmd = 0; mCurrHistroy = -1; mHasFull = FALSE; mMainWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); int w = gParams->valuei ("width"); int h = gParams->valuei ("height"); if (gParams->valueb ("fullscreen")) { GdkScreen *scr = gdk_screen_get_default (); mWidth = gdk_screen_get_width (scr); mHeight = gdk_screen_get_height (scr); fullscreen (); } else { mWidth = w; mHeight = h; gtk_window_set_default_size (GTK_WINDOW (mMainWindow), w > 1 ? w : 800, h > 1 ? h : 600); } mViewBox = gtk_vbox_new (FALSE, 0); gtk_container_add (GTK_CONTAINER (mMainWindow), mViewBox); mMenu = new ApvlvMenu (); if (strchr (gParams->values ("guioptions"), 'm') != NULL) { mMenu->setsize (mWidth, APVLV_MENU_HEIGHT - 1); gtk_box_pack_start (GTK_BOX (mViewBox), mMenu->widget (), FALSE, FALSE, 0); } mTabContainer = gtk_notebook_new (); gtk_notebook_set_show_tabs (GTK_NOTEBOOK (mTabContainer), FALSE); gtk_notebook_set_scrollable (GTK_NOTEBOOK (mTabContainer), TRUE); gtk_box_pack_start (GTK_BOX (mViewBox), mTabContainer, TRUE, TRUE, 0); if (newtab (filename) == false) { bool ret = false; gchar *rpath = absolutepath (helppdf.c_str ()); if (rpath) { ret = newtab (rpath); g_free (rpath); } if (ret == false) { exit (1); } } mCommandBar = gtk_entry_new (); gtk_box_pack_end (GTK_BOX (mViewBox), mCommandBar, FALSE, FALSE, 0); g_signal_connect (G_OBJECT (mMainWindow), "size-allocate", G_CALLBACK (apvlv_view_resized_cb), this); g_signal_connect (G_OBJECT (mMainWindow), "key-press-event", G_CALLBACK (apvlv_view_keypress_cb), this); g_signal_connect (G_OBJECT (mMainWindow), "delete-event", G_CALLBACK (apvlv_view_delete_cb), this); g_signal_connect (G_OBJECT (mMainWindow), "destroy-event", G_CALLBACK (apvlv_view_delete_cb), this); g_signal_connect (G_OBJECT (mTabContainer), "switch-page", G_CALLBACK (apvlv_notebook_switch_cb), this); g_signal_connect (G_OBJECT (mCommandBar), "key-press-event", G_CALLBACK (apvlv_view_commandbar_cb), this); gtk_widget_show_all (mMainWindow); cmd_hide (); } ApvlvView::~ApvlvView () { size_t i; delete mMenu; for (int i = 0; i < (int) mTabList.size (); i++) { delete mTabList[i].root; } mTabList.clear (); mCmdHistroy.clear (); for (i = 0; i < mDocs.size (); ++i) { ApvlvCore *core = (ApvlvCore *) mDocs[i]; delete core; } } void ApvlvView::show () { gtk_main (); } GtkWidget *ApvlvView::widget () { return mMainWindow; } ApvlvWindow *ApvlvView::currentWindow () { return ApvlvWindow::currentWindow (); } void ApvlvView::delcurrentWindow () { ApvlvWindow::delcurrentWindow (); mTabList[mCurrTabPos].numwindows--; updatetabname (); } void ApvlvView::open () { gchar *dirname; GtkWidget *dia = gtk_file_chooser_dialog_new ("Open ...", GTK_WINDOW (mMainWindow), GTK_FILE_CHOOSER_ACTION_SAVE, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); infofile *fp = gInfo->file (0); dirname = fp ? g_dirname (fp->file.c_str ()) : g_strdup (gParams->values ("defaultdir")); debug ("lastfile: [%s], dirname: [%s]", fp ? fp->file.c_str () : "", dirname); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dia), dirname); g_free (dirname); GtkFileFilter *filter = gtk_file_filter_new (); gtk_file_filter_add_mime_type (filter, "PDF File"); gtk_file_filter_add_pattern (filter, "*.pdf"); gtk_file_filter_add_pattern (filter, "*.PDF"); #ifdef HAVE_LIBDJVU gtk_file_filter_add_mime_type (filter, "DJVU File"); gtk_file_filter_add_pattern (filter, "*.djvu"); #endif #ifdef HAVE_LIBUMD gtk_file_filter_add_mime_type (filter, "UMD File"); gtk_file_filter_add_pattern (filter, "*.UMD"); gtk_file_filter_add_pattern (filter, "*.umd"); #endif gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dia), filter); gint ret = gtk_dialog_run (GTK_DIALOG (dia)); if (ret == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dia)); loadfile (filename); g_free (filename); } gtk_widget_destroy (dia); } void ApvlvView::opendir () { gchar *dirname; GtkWidget *dia = gtk_file_chooser_dialog_new ("", GTK_WINDOW (mMainWindow), GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_ACCEPT, NULL); infofile *fp = gInfo->file (0); dirname = fp ? g_dirname (fp->file.c_str ()) : g_strdup (gParams->values ("defaultdir")); gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dia), dirname); g_free (dirname); gint ret = gtk_dialog_run (GTK_DIALOG (dia)); if (ret == GTK_RESPONSE_ACCEPT) { gchar *filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dia)); loaddir (filename); g_free (filename); } gtk_widget_destroy (dia); } bool ApvlvView::loaddir (const char *path) { ApvlvCore *ndoc = hasloaded (path, CORE_DIR); if (ndoc == NULL) { int w, h; currentWindow ()->getsize (&w, &h); ndoc = new ApvlvDir (w, h); if (!ndoc->loadfile (path)) { delete ndoc; return false; } regloaded (ndoc); } currentWindow ()->setCore (ndoc); updatetabname (); return true; } bool ApvlvView::loadfile (string file) { return loadfile (file.c_str ()); } void ApvlvView::quit () { if ((int) mTabList.size () == 1) { mTabList.clear (); apvlv_view_delete_cb (NULL, NULL, this); return; } int p = mCurrTabPos; if (mCurrTabPos < (int) mTabList.size () - 1) switch_tabcontext (mCurrTabPos + 1); else switch_tabcontext (mCurrTabPos - 1); gtk_notebook_set_current_page (GTK_NOTEBOOK (mTabContainer), mCurrTabPos); mRootWindow->setsize (mWidth, adjheight ()); gtk_notebook_remove_page (GTK_NOTEBOOK (mTabContainer), p); delete_tabcontext (p); if (mCurrTabPos > p) --mCurrTabPos; mRootWindow->setsize (mWidth, adjheight ()); } bool ApvlvView::newtab (const char *filename) { ApvlvCore *ndoc; ndoc = hasloaded (filename, gParams->valueb ("content") ? CORE_CONTENT : CORE_DOC); if (ndoc == NULL) { if (gParams->valueb ("content")) { ndoc = new ApvlvDir (mWidth, adjheight ()); if (!ndoc->loadfile (filename)) { delete ndoc; ndoc = NULL; } } if (ndoc == NULL) { ndoc = new ApvlvDoc (mWidth, mHeight, gParams->values ("zoom"), false); if (!ndoc->loadfile (filename)) { delete ndoc; ndoc = NULL; } } if (ndoc) { regloaded (ndoc); } } if (ndoc) { newtab (ndoc); return true; } else { return false; } } bool ApvlvView::newtab (ApvlvCore * core) { int pos = new_tabcontext (core, true); switch_tabcontext (pos); mRootWindow->setsize (mWidth, adjheight ()); gchar *base = core->filename ()? g_path_get_basename (core->filename ()) : g_strdup ("NONE"); GtkWidget *tabname = gtk_label_new (base); g_free (base); GtkWidget *parentbox = gtk_vbox_new (false, 0); gtk_container_add (GTK_CONTAINER (parentbox), mTabList[mCurrTabPos].root->widget ()); gtk_notebook_insert_page (GTK_NOTEBOOK (mTabContainer), parentbox, tabname, pos); gtk_widget_show_all (parentbox); gtk_notebook_set_current_page (GTK_NOTEBOOK (mTabContainer), mCurrTabPos); return true; } int ApvlvView::new_tabcontext (ApvlvCore * core, bool insertAfterCurr) { ApvlvWindow *troot = new ApvlvWindow (core); TabEntry context (troot, troot, 1); if (!insertAfterCurr || mCurrTabPos == -1) { mTabList.push_back (context); return mTabList.size () - 1; } std::vector < TabEntry >::iterator insPos = mTabList.begin () + mCurrTabPos + 1; mTabList.insert (insPos, context); if (mTabList.size () > 1) { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (mTabContainer), TRUE); gtk_widget_set_size_request (mTabContainer, mWidth - 12, 12); } return mCurrTabPos + 1; } void ApvlvView::delete_tabcontext (int tabPos) { asst (tabPos >= 0 && tabPos < (int) mTabList.size ()); std::vector < TabEntry >::iterator remPos = mTabList.begin () + tabPos; if (remPos->root != NULL) { delete remPos->root; remPos->root = NULL; } int c = mTabList.size (); mTabList.erase (remPos); if (c == (int) mTabList.size ()) { gView->errormessage ("erase failed to remove context"); } if ((int) mTabList.size () <= 1) { gtk_notebook_set_show_tabs (GTK_NOTEBOOK (mTabContainer), FALSE); } } void ApvlvView::switch_tabcontext (int tabPos) { asst (tabPos >= 0 && tabPos < (int) mTabList.size ()); if (mCurrTabPos != -1) mTabList[mCurrTabPos].curr = currentWindow (); mCurrTabPos = tabPos; mRootWindow = mTabList[tabPos].root; ApvlvWindow::setcurrentWindow (NULL, mTabList[tabPos].curr); if (crtadoc () && crtadoc ()->filename ()) { gchar *base = g_path_get_basename (crtadoc ()->filename ()); settitle (base); g_free (base); } } bool ApvlvView::loadfile (const char *filename) { if (filename == NULL || *filename == '\0') { return false; } char *abpath = absolutepath (filename); if (abpath == NULL) { return false; } ApvlvWindow *win = ApvlvWindow::currentWindow (); ApvlvCore *ndoc; ndoc = hasloaded (abpath, gParams->valueb ("content") ? CORE_CONTENT : CORE_DOC); if (ndoc == NULL) { int w, h; win->getsize (&w, &h); if (gParams->valueb ("content")) { ndoc = new ApvlvDir (w, h); if (!ndoc->loadfile (abpath)) { debug ("can't load"); delete ndoc; ndoc = NULL; } } if (ndoc == NULL) { ndoc = new ApvlvDoc (w, h, gParams->values ("zoom"), false); if (!ndoc->loadfile (filename)) { delete ndoc; ndoc = NULL; } } if (ndoc != NULL) { regloaded (ndoc); } } if (ndoc != NULL) { win->setCore (ndoc); updatetabname (); } g_free (abpath); return ndoc != NULL ? true : false; } ApvlvCore *ApvlvView::hasloaded (const char *abpath, int type) { ApvlvCore *core; size_t i; for (i = 0; i < mDocs.size (); ++i) { core = (ApvlvCore *) mDocs[i]; if (core->inuse () == false && core->type () == type && strcmp (core->filename (), abpath) == 0) { return core; } } return NULL; } void ApvlvView::regloaded (ApvlvCore * core) { if (gParams->valuei ("pdfcache") < 2) { gParams->push ("pdfcache", "2"); } if (mDocs.size () >= (size_t) gParams->valuei ("pdfcache")) { std::vector < ApvlvCore * >::iterator itr = mDocs.begin (); debug ("to pdf cache size: %d, remove first: %p\n", gParams->valuei ("pdfcache"), *itr); mDocs.erase (itr); } mDocs.push_back (core); } GCompletion *ApvlvView::filecompleteinit (const char *path) { GCompletion *gcomp = g_completion_new (NULL); GList *list = g_list_alloc (); gchar *dname, *bname; const gchar *name; dname = g_path_get_dirname (path); GDir *dir = g_dir_open ((const char *) dname, 0, NULL); if (dir != NULL) { bname = g_path_get_basename (path); size_t len = strlen (bname); while ((name = g_dir_read_name (dir)) != NULL) { gchar *fname = g_locale_from_utf8 (name, -1, NULL, NULL, NULL); if (strcmp (bname, PATH_SEP_S) != 0) { if (strncmp (fname, bname, len) != 0) { g_free (fname); continue; } } if (strcmp (dname, ".") == 0) { list->data = g_strdup (fname); } else { if (dname[strlen (dname) - 1] == PATH_SEP_C) { list->data = g_strjoin ("", dname, fname, NULL); } else { list->data = g_strjoin (PATH_SEP_S, dname, fname, NULL); } } g_free (fname); debug ("add a item: %s", (char *) list->data); g_completion_add_items (gcomp, list); } g_free (bname); g_dir_close (dir); } g_free (dname); g_list_free (list); return gcomp; } void ApvlvView::promptcommand (char ch) { char s[2] = { 0 }; s[0] = ch; gtk_entry_set_text (GTK_ENTRY (mCommandBar), s); cmd_show (CMD_CMD); } void ApvlvView::promptcommand (const char *s) { gtk_entry_set_text (GTK_ENTRY (mCommandBar), s); cmd_show (CMD_CMD); } void ApvlvView::errormessage (const char *str, ...) { gchar estr[512]; va_list vap; va_start (vap, str); vsnprintf (estr, sizeof estr, str, vap); va_end (vap); gtk_entry_set_text (GTK_ENTRY (mCommandBar), "ERROR: "); gtk_entry_append_text (GTK_ENTRY (mCommandBar), estr); cmd_show (CMD_MESSAGE); } void ApvlvView::infomessage (const char *str, ...) { gchar estr[512]; va_list vap; va_start (vap, str); vsnprintf (estr, sizeof estr, str, vap); va_end (vap); gtk_entry_set_text (GTK_ENTRY (mCommandBar), "INFO: "); gtk_entry_append_text (GTK_ENTRY (mCommandBar), estr); cmd_show (CMD_MESSAGE); } void ApvlvView::cmd_show (int cmdtype) { if (mMainWindow == NULL) return; mCmdType = cmdtype; mRootWindow->setsize (mWidth, adjheight ()); gtk_widget_show (mCommandBar); gtk_widget_grab_focus (mCommandBar); gtk_entry_set_position (GTK_ENTRY (mCommandBar), -1); } void ApvlvView::cmd_hide () { if (mMainWindow == NULL) return; mCmdType = CMD_NONE; gtk_widget_hide (mCommandBar); mRootWindow->setsize (mWidth, adjheight ()); gtk_widget_grab_focus (mMainWindow); } void ApvlvView::cmd_auto (const char *ps) { GCompletion *gcomp = NULL; stringstream ss (ps); string cmd, np, argu; ss >> cmd >> np >> argu; if (np[np.length () - 1] == '\\') { np.replace (np.length () - 1, 1, 1, ' '); np += argu; ss >> argu; } if (cmd == "" || np == "") { return; } if (cmd == "o" || cmd == "open" || cmd == "TOtext") { gcomp = filecompleteinit (np.c_str ()); } else if (cmd == "doc") { gcomp = g_completion_new (NULL); GList *list = g_list_alloc (); size_t i; for (i = 0; i < mDocs.size (); ++i) { list->data = g_strdup (((ApvlvCore *) mDocs[i])->filename ()); g_completion_add_items (gcomp, list); } g_list_free (list); } if (gcomp != NULL) { char *comtext = NULL; debug ("find match: %s", np.c_str ()); g_completion_complete (gcomp, np.c_str (), &comtext); if (comtext != NULL) { char text[PATH_MAX]; debug ("get a match: %s", comtext); gchar **v; v = g_strsplit (comtext, " ", -1); if (v != NULL) { gchar *comstr = g_strjoinv ("\\ ", v); g_snprintf (text, sizeof text, ":%s %s", cmd.c_str (), comstr); g_free (comstr); g_strfreev (v); } else { g_snprintf (text, sizeof text, ":%s %s", cmd.c_str (), comtext); } gtk_entry_set_text (GTK_ENTRY (mCommandBar), text); gtk_editable_set_position (GTK_EDITABLE (mCommandBar), -1); g_free (comtext); } else { debug ("no get match"); } g_completion_free (gcomp); } } void ApvlvView::fullscreen () { if (mHasFull == false) { gtk_window_fullscreen (GTK_WINDOW (mMainWindow)); mHasFull = true; } else { gtk_window_unfullscreen (GTK_WINDOW (mMainWindow)); mHasFull = false; } } ApvlvCore *ApvlvView::crtadoc () { return currentWindow ()->getCore (); } returnType ApvlvView::subprocess (int ct, guint key) { guint procmd = mProCmd; mProCmd = 0; switch (procmd) { case CTRL ('w'): if (key == 'q' || key == CTRL ('Q')) { if (currentWindow ()->istop ()) { quit (); } else { delcurrentWindow (); } } else { returnType rv = currentWindow ()->process (ct, key); updatetabname (); return rv; } break; case 'g': if (ct == 0) ct = 1; if (key == 't') switchtab (mCurrTabPos + ct); else if (key == 'T') switchtab (mCurrTabPos - ct); else if (key == 'g') crtadoc ()->showpage (0); break; default: return NO_MATCH; break; } return MATCH; } returnType ApvlvView::process (int has, int ct, guint key) { if (mProCmd != 0) { return subprocess (ct, key); } switch (key) { case CTRL ('w'): mProCmd = CTRL ('w'); return NEED_MORE; break; case 'q': quit (); break; case 'f': fullscreen (); break; case 'g': mProCmd = 'g'; return NEED_MORE; default: return crtadoc ()->process (has, ct, key); break; } return MATCH; } bool ApvlvView::run (const char *str) { bool ret; switch (*str) { case SEARCH: crtadoc ()->markposition ('\''); ret = crtadoc ()->search (str + 1); break; case BACKSEARCH: crtadoc ()->markposition ('\''); ret = crtadoc ()->search (str + 1, true); break; case COMMANDMODE: ret = runcmd (str + 1); break; default: ret = false; break; } return ret; } void ApvlvView::settitle (const char *title) { gtk_window_set_title (GTK_WINDOW (mMainWindow), title); } bool ApvlvView::runcmd (const char *str) { bool ret = true; if (*str == '!') { apvlv_system (str + 1); } else { stringstream ss (str); string cmd, subcmd, argu; ss >> cmd >> subcmd >> argu; if (subcmd.length () > 0 && subcmd[subcmd.length () - 1] == '\\') { subcmd.replace (subcmd.length () - 1, 1, 1, ' '); subcmd += argu; ss >> argu; } if (cmd == "set") { if (subcmd == "cache") { gParams->push ("cache", "yes"); crtadoc ()->usecache (true); } else if (subcmd == "nocache") { gParams->push ("cache", "no"); crtadoc ()->usecache (false); } else if (subcmd == "skip") { crtadoc ()->setskip (atoi (argu.c_str ())); } else { gParams->push (subcmd, argu); } } else if (cmd == "map" && subcmd != "") { gCmds->buildmap (subcmd.c_str (), argu.c_str ()); } else if ((cmd == "o" || cmd == "open" || cmd == "doc") && subcmd != "") { if (g_file_test (subcmd.c_str (), G_FILE_TEST_IS_DIR)) { ret = loaddir (subcmd.c_str ()); } else if (g_file_test (subcmd.c_str (), G_FILE_TEST_EXISTS)) { ret = loadfile (subcmd.c_str ()); } else { errormessage ("no file '%s'", subcmd.c_str ()); ret = false; } } else if (cmd == "TOtext" && subcmd != "") { crtadoc ()->totext (subcmd.c_str ()); } else if ((cmd == "pr" || cmd == "print")) { crtadoc ()->print (subcmd == "" ? -1 : atoi (subcmd.c_str ())); } else if (cmd == "sp") { currentWindow ()->birth (false); windowadded (); } else if (cmd == "vsp") { currentWindow ()->birth (true); windowadded (); } else if ((cmd == "zoom" || cmd == "z") && subcmd != "") { crtadoc ()->setzoom (subcmd.c_str ()); } else if (cmd == "forwardpage" || cmd == "fp") { if (subcmd == "") crtadoc ()->nextpage (1); else crtadoc ()->nextpage (atoi (subcmd.c_str ())); } else if (cmd == "prewardpage" || cmd == "bp") { if (subcmd == "") crtadoc ()->prepage (1); else crtadoc ()->prepage (atoi (subcmd.c_str ())); } else if (cmd == "goto" || cmd == "g") { crtadoc ()->markposition ('\''); int p = atoi (subcmd.c_str ()); p += crtadoc ()->getskip (); crtadoc ()->showpage (p - 1); } else if ((cmd == "help" || cmd == "h") && subcmd == "info") { loadfile (helppdf); crtadoc ()->showpage (1); } else if ((cmd == "help" || cmd == "h") && subcmd == "command") { loadfile (helppdf); crtadoc ()->showpage (3); } else if ((cmd == "help" || cmd == "h") && subcmd == "setting") { crtadoc ()->loadfile (helppdf.c_str ()); crtadoc ()->showpage (8); } else if ((cmd == "help" || cmd == "h") && subcmd == "prompt") { crtadoc ()->loadfile (helppdf.c_str ()); crtadoc ()->showpage (8); } else if (cmd == "help" || cmd == "h") { loadfile (helppdf); } else if (cmd == "q" || cmd == "quit") { if (currentWindow ()->istop ()) { quit (); } else { delcurrentWindow (); } } else if (cmd == "qall") { while (!mTabList.empty ()) { if (currentWindow ()->istop ()) { quit (); } else { delcurrentWindow (); } } } else if (cmd == "tabnew") { newtab (helppdf.c_str ()); } else if (cmd == "tabn" || cmd == "tabnext") { switchtab (mCurrTabPos + 1); } else if (cmd == "tabp" || cmd == "tabprevious") { switchtab (mCurrTabPos - 1); } else if (cmd == "w" || cmd == "write") { crtadoc ()->writefile (subcmd.size () > 0 ? subcmd.c_str () : NULL); } else { bool isn = true; for (size_t i = 0; i < cmd.length (); ++i) { if (cmd[i] < '0' || cmd[i] > '9') { isn = false; break; } } if (isn && crtadoc ()) { int p = atoi (cmd.c_str ()); p += crtadoc ()->getskip (); if (p != crtadoc ()->pagenumber ()) { crtadoc ()->showpage (p - 1); } } else { errormessage ("no command: '%s'", cmd.c_str ()); ret = false; } } } return ret; } void ApvlvView::apvlv_view_resized_cb (GtkWidget * wid, GtkAllocation * al, ApvlvView * view) { int w, h; w = view->mViewBox->allocation.width - 12; h = view->mViewBox->allocation.height - 12; if (w != view->mWidth || h != view->mHeight) { view->mWidth = w; view->mHeight = h; view->mRootWindow->setsize (w, view->adjheight () - 10); } } gint ApvlvView::apvlv_view_keypress_cb (GtkWidget * wid, GdkEvent * ev, ApvlvView * view) { if (view->mCmdType == CMD_NONE) { gCmds->append ((GdkEventKey *) ev); return TRUE; } return FALSE; } gint ApvlvView::apvlv_view_commandbar_cb (GtkWidget * wid, GdkEvent * ev, ApvlvView * view) { if (view->mCmdType == CMD_CMD) { view->mInHistroy = false; GdkEventKey *gek = (GdkEventKey *) ev; if (gek->keyval == GDK_Return) { gchar *str = (gchar *) gtk_entry_get_text (GTK_ENTRY (view->mCommandBar)); if (str && strlen (str) > 0) { if (view->run (str) == true) { view->mCmdHistroy.push_back (str); view->mCurrHistroy = view->mCmdHistroy.size () - 1; view->cmd_hide (); return TRUE; } else { debug (""); return TRUE; } } else { view->cmd_hide (); return TRUE; } } else if (gek->keyval == GDK_Tab) { gchar *str = (gchar *) gtk_entry_get_text (GTK_ENTRY (view->mCommandBar)); if (str && strlen (str) > 0) { view->cmd_auto (str + 1); } return TRUE; } else if (gek->keyval == GDK_BackSpace) { gchar *str = (gchar *) gtk_entry_get_text (GTK_ENTRY (view->mCommandBar)); if (str == NULL || strlen (str) == 1) { view->cmd_hide (); view->mCurrHistroy = view->mCmdHistroy.size () - 1; return TRUE; } } else if (gek->keyval == GDK_Escape) { view->cmd_hide (); view->mCurrHistroy = view->mCmdHistroy.size () - 1; return TRUE; } else if (gek->keyval == GDK_Up) { if (view->mCmdHistroy.size () == 0) { return TRUE; } view->mInHistroy = true; gtk_entry_set_text (GTK_ENTRY (view->mCommandBar), view->mCurrHistroy > 0 ? view->mCmdHistroy[view-> mCurrHistroy--].c_str () : view->mCmdHistroy[0].c_str ()); return TRUE; } else if (gek->keyval == GDK_Down) { if (view->mCmdHistroy.size () == 0) { return TRUE; } view->mInHistroy = true; gtk_entry_set_text (GTK_ENTRY (view->mCommandBar), (size_t) view->mCurrHistroy < view->mCmdHistroy.size () - 1 ? view->mCmdHistroy[++view-> mCurrHistroy].c_str () : view->mCmdHistroy[view->mCmdHistroy.size () - 1].c_str ()); return TRUE; } return FALSE; } else if (view->mCmdType == CMD_MESSAGE) { debug (""); view->cmd_hide (); return TRUE; } return FALSE; } void ApvlvView::apvlv_view_delete_cb (GtkWidget * wid, GtkAllocation * al, ApvlvView * view) { view->mMainWindow = NULL; gtk_main_quit (); } void ApvlvView::apvlv_notebook_switch_cb (GtkWidget * wid, GtkNotebookPage * page, guint pnum, ApvlvView * view) { view->mCurrTabPos = pnum; view->mRootWindow = view->mTabList[pnum].root; ApvlvWindow::setcurrentWindow (NULL, view->mTabList[pnum].curr); } int ApvlvView::adjheight () { int adj = 0; if (gtk_notebook_get_show_tabs (GTK_NOTEBOOK (mTabContainer))) { adj += APVLV_TABS_HEIGHT; } if (mCmdType != CMD_NONE) { adj += APVLV_CMD_BAR_HEIGHT; } if (strchr (gParams->values ("guioptions"), 'm') != NULL) { adj += APVLV_MENU_HEIGHT; } return mHeight - adj; } void ApvlvView::switchtab (int tabPos) { int ntabs = mTabList.size (); while (tabPos < 0) tabPos += ntabs; tabPos = tabPos % ntabs; switch_tabcontext (tabPos); mRootWindow->setsize (mWidth, adjheight ()); gtk_notebook_set_current_page (GTK_NOTEBOOK (mTabContainer), mCurrTabPos); } void ApvlvView::windowadded () { mTabList[mCurrTabPos].numwindows++; updatetabname (); } void ApvlvView::updatetabname () { char tagname[26]; const char *filename = currentWindow ()->getCore ()->filename (); gchar *gfilename; if (filename == NULL) gfilename = g_strdup ("None"); else gfilename = g_path_get_basename (filename); settitle (gfilename); if (mTabList[mCurrTabPos].numwindows > 1) g_snprintf (tagname, sizeof tagname, "[%d] %s", mTabList[mCurrTabPos].numwindows, gfilename); else g_snprintf (tagname, sizeof tagname, "%s", gfilename); g_free (gfilename); GtkWidget *tabname = gtk_label_new (tagname); GtkWidget *tabwidget = gtk_notebook_get_nth_page (GTK_NOTEBOOK (mTabContainer), mCurrTabPos); gtk_notebook_set_tab_label (GTK_NOTEBOOK (mTabContainer), tabwidget, tabname); gtk_notebook_set_current_page (GTK_NOTEBOOK (mTabContainer), mCurrTabPos); } } apvlv-0.1.1-Source/src/ApvlvParams.hpp100644 1750 1750 3251 11521211167 16710 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvParams.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_PARAMS_H_ #define _APVLV_PARAMS_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvUtil.hpp" #include #include #include using namespace std; namespace apvlv { typedef map < string, string > ApvlvParam; class ApvlvParams { public: ApvlvParams (); ~ApvlvParams (); bool loadfile (const char *filename); bool push (string & ch, string & str); bool push (const char *c, const char *s); const char *values (const char *key); int valuei (const char *key); double valuef (const char *key); bool valueb (const char *key); private: ApvlvParam mSettings; }; extern ApvlvParams *gParams; } #endif apvlv-0.1.1-Source/src/ApvlvMenu.cpp100644 1750 1750 14043 11521211167 16405 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvMenu.cpp * * Author: Alf */ /* @date Created: 2010/01/21 15:09:58 Alf*/ #include "ApvlvView.hpp" #include "ApvlvMenu.hpp" namespace apvlv { static void apvlv_menu_on_file_open (); static void apvlv_menu_on_file_opentab (); static void apvlv_menu_on_file_saveas (); static void apvlv_menu_on_file_print (); static void apvlv_menu_on_file_quit (); static void apvlv_menu_on_page_prev (); static void apvlv_menu_on_page_next (); static void apvlv_menu_on_page_scrollup (); static void apvlv_menu_on_page_scrolldown (); static void apvlv_menu_on_tools_jumpto (); static void apvlv_menu_on_tools_jumpback (); static void apvlv_menu_on_help_about (); ApvlvMenu::ApvlvMenu () { const GtkActionEntry action_entries[] = { {"File", NULL, "File", NULL, NULL, NULL}, {"Open", NULL, "Open", NULL, NULL, apvlv_menu_on_file_open}, {"OpenTab", ":tabnew", "Open Tab...", NULL, NULL, apvlv_menu_on_file_opentab}, {"SaveAs", ":w", "Save As...", NULL, NULL, apvlv_menu_on_file_saveas}, {"Print", ":p[rint]", "Print", NULL, NULL, apvlv_menu_on_file_print}, {"Quit", ":q[uit]", "Quit", NULL, NULL, apvlv_menu_on_file_quit}, {"Page", NULL, "Page", NULL, NULL, NULL}, {"Previous", "", "Previous", NULL, NULL, apvlv_menu_on_page_prev}, {"Next", "", "Next", NULL, NULL, apvlv_menu_on_page_next}, {"ScrollUp", "", "ScrollUp", NULL, NULL, apvlv_menu_on_page_scrollup}, {"ScrollDown", "", "ScrollDown", NULL, NULL, apvlv_menu_on_page_scrolldown}, {"Tools", NULL, "Tools", NULL, NULL, NULL}, {"JumpTo", "]", "JumpTo", NULL, NULL, apvlv_menu_on_tools_jumpto}, {"JumpBack", "t", "JumpBack", NULL, NULL, apvlv_menu_on_tools_jumpback}, {"Help", NULL, "Help", NULL, NULL, NULL}, {"About", NULL, "About", NULL, NULL, apvlv_menu_on_help_about}, }; const char *menu_string = "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" "" ""; GtkUIManager *manager = gtk_ui_manager_new (); GtkActionGroup *group = gtk_action_group_new ("action"); gtk_action_group_add_actions (group, action_entries, sizeof (action_entries) / sizeof (action_entries[0]), NULL); gtk_ui_manager_insert_action_group (manager, group, 0); gtk_ui_manager_add_ui_from_string (manager, menu_string, -1, NULL); mMenu = gtk_ui_manager_get_widget (manager, "/ui/menubar"); } ApvlvMenu::~ApvlvMenu () { } GtkWidget *ApvlvMenu::widget () { return mMenu; } void ApvlvMenu::setsize (gint w, gint h) { gtk_widget_set_size_request (mMenu, w, h); } static void apvlv_menu_on_file_open () { gView->open (); } static void apvlv_menu_on_file_opentab () { gView->newtab (helppdf.c_str ()); } static void apvlv_menu_on_file_saveas () { // gView->save (); } static void apvlv_menu_on_file_print () { // gView->print (); } static void apvlv_menu_on_file_quit () { gView->quit (); } static void apvlv_menu_on_page_prev () { gView->crtadoc ()->prepage (1); } static void apvlv_menu_on_page_next () { gView->crtadoc ()->nextpage (1); } static void apvlv_menu_on_page_scrollup () { gView->crtadoc ()->scrollup (1); } static void apvlv_menu_on_page_scrolldown () { gView->crtadoc ()->scrolldown (1); } static void apvlv_menu_on_tools_jumpto () { gView->crtadoc ()->gotolink (1); } static void apvlv_menu_on_tools_jumpback () { gView->crtadoc ()->returnlink (1); } static void apvlv_menu_on_help_about () { GtkWidget *dia = NULL; static const char *author[] = { "Alf", NULL }; dia = gtk_about_dialog_new (); gtk_about_dialog_set_name (GTK_ABOUT_DIALOG (dia), PACKAGE_NAME); gtk_about_dialog_set_version (GTK_ABOUT_DIALOG (dia), PACKAGE_VERSION); gtk_about_dialog_set_authors (GTK_ABOUT_DIALOG (dia), author); gtk_about_dialog_set_artists (GTK_ABOUT_DIALOG (dia), author); gtk_about_dialog_set_website (GTK_ABOUT_DIALOG (dia), "http://naihe2010.cublog.cn"); gtk_about_dialog_set_copyright (GTK_ABOUT_DIALOG (dia), "GNU"); gtk_dialog_run (GTK_DIALOG (dia)); gtk_widget_destroy (dia); } }; apvlv-0.1.1-Source/src/ApvlvFile.cpp100644 1750 1750 52176 11521211167 16371 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvFile.cpp xxxxxxxxxxxxxxxxxxxxxxxxxx. * * Author: Alf */ /* @date Created: 2009/11/20 19:38:30 Alf*/ #include "ApvlvFile.hpp" #include "ApvlvUtil.hpp" #include "ApvlvView.hpp" #ifdef HAVE_LIBUMD #define LIBUMD_ENABLE_GTK #include #endif #include #include #include #include namespace apvlv { #ifndef MAX #define MAX(a,b) ((a) > (b) ? (a) : (b)) #endif ApvlvFile::ApvlvFile (const char *filename, bool check) { mIndex = NULL; mRawdata = NULL; mRawdataSize = 0; } ApvlvFile::~ApvlvFile () { if (mRawdata != NULL) { delete[]mRawdata; mRawdata = NULL; } } ApvlvFile *ApvlvFile::newfile (const char *filename, bool check) { ApvlvFile *file = NULL; static const char *type_phrase[] = { ".PDF", ".umd", ".djvu" }; size_t i; for (i = 0; i < 3; ++ i) { if (strcasecmp (filename + strlen (filename) - strlen (type_phrase[i]), type_phrase[i]) == 0) { break; } } if (i == 3) { debug ("not a valid file: %s, treate as a PDF file", filename); i = 0; } try { switch (i) { case 0: file = new ApvlvPDF (filename); break; case 1: file = new ApvlvUMD (filename); break; case 2: file = new ApvlvDJVU (filename); break; default: ; } } catch (bad_alloc e) { delete file; file = NULL; } return file; } ApvlvPDF::ApvlvPDF (const char *filename, bool check):ApvlvFile (filename, check) { gchar *wfilename; if (filename == NULL || *filename == '\0' || g_file_test (filename, G_FILE_TEST_IS_REGULAR) == FALSE || (wfilename = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL)) == NULL) { gView->errormessage ("filename error: %s", filename ? filename : "No name"); throw std::bad_alloc (); } size_t filelen; struct stat sbuf; int rt = stat (wfilename, &sbuf); if (rt < 0) { gView->errormessage ("Can't stat the PDF file: %s.", filename); throw std::bad_alloc (); } filelen = sbuf.st_size; if (mRawdata != NULL && mRawdataSize < filelen) { delete[]mRawdata; mRawdata = NULL; } if (mRawdata == NULL) { mRawdata = new char[filelen]; mRawdataSize = filelen; } ifstream ifs (wfilename, ios::binary); if (ifs.is_open ()) { ifs.read (mRawdata, filelen); ifs.close (); } g_free (wfilename); GError *error = NULL; mDoc = poppler_document_new_from_data (mRawdata, filelen, NULL, &error); if (mDoc == NULL && error && error->code == POPPLER_ERROR_ENCRYPTED) { GtkWidget *dia = gtk_message_dialog_new (NULL, GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_OK_CANCEL, "%s", error->message); g_error_free (error); GtkWidget *entry = gtk_entry_new (); gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); gtk_entry_set_invisible_char (GTK_ENTRY (entry), '*'); gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dia)->vbox), entry, TRUE, TRUE, 10); gtk_widget_show (entry); int ret = gtk_dialog_run (GTK_DIALOG (dia)); if (ret == GTK_RESPONSE_OK) { gchar *ans = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry)); if (ans != NULL) { mDoc = poppler_document_new_from_data (mRawdata, filelen, ans, NULL); } } gtk_widget_destroy (dia); } if (mDoc == NULL) { throw std::bad_alloc (); } } ApvlvPDF::~ApvlvPDF () { if (mDoc) { g_object_unref (mDoc); } } bool ApvlvPDF::writefile (const char *filename) { debug ("write %p to %s", this, filename); gchar *path = absolutepath (filename); if (path == NULL) { debug ("filename error: %s", filename); return false; } GError *error = NULL; gchar *uri = g_filename_to_uri (path, NULL, &error); g_free (path); if (uri == NULL && error) { debug ("%d: %s", error->code, error->message); return false; } if (mDoc && uri != NULL) { gboolean ret = poppler_document_save (mDoc, uri, NULL); debug ("write pdf: %p to %s, return %d", mDoc, uri, ret); g_free (uri); return ret == TRUE ? true : false; } return false; } bool ApvlvPDF::pagesize (int pn, int rot, double *x, double *y) { PopplerPage *page = poppler_document_get_page (mDoc, pn); if (page != NULL) { if (rot == 90 || rot == 270) { poppler_page_get_size (page, y, x); } else { poppler_page_get_size (page, x, y); } return true; } return false; } int ApvlvPDF::pagesum () { return mDoc ? poppler_document_get_n_pages (mDoc) : 0; } ApvlvPoses *ApvlvPDF::pagesearch (int pn, const char *str, bool reverse) { PopplerPage *page = poppler_document_get_page (mDoc, pn); if (page == NULL) { return NULL; } // debug ("search %s", str); GList *list = poppler_page_find_text (page, str); if (list == NULL) { return NULL; } if (reverse) { list = g_list_reverse (list); } ApvlvPoses *poses = new ApvlvPoses; for (GList * tmp = list; tmp != NULL; tmp = g_list_next (tmp)) { PopplerRectangle *rect = (PopplerRectangle *) tmp->data; // debug ("results: %f-%f,%f-%f", rect->x1, rect->x2, rect->y1, // rect->y2); ApvlvPos pos = { rect->x1, rect->x2, rect->y1, rect->y2 }; poses->push_back (pos); } return poses; } bool ApvlvPDF::pagetext (int pn, int x1, int y1, int x2, int y2, char **out) { PopplerRectangle rect = { x1, y1, x2, y2 }; PopplerPage *page = poppler_document_get_page (mDoc, pn); *out = poppler_page_get_text (page, POPPLER_SELECTION_WORD, &rect); if (*out != NULL) { return true; } return false; } bool ApvlvPDF::render (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer) { PopplerPage *tpage; if ((tpage = poppler_document_get_page (mDoc, pn)) == NULL) { debug ("no this page: %d", pn); return false; } poppler_page_render_to_pixbuf (tpage, 0, 0, ix, iy, zm, rot, pix); return true; } bool ApvlvPDF::pageselectsearch (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer, int sel, ApvlvPoses * poses) { ApvlvPos rect = (*poses)[sel]; // Caculate the correct position //debug ("pagex: %f, pagey: %f, x1: %f, y1: %f, x2: %f, y2: %f", pagex, pagey, rect->x1, rect->y1, rect->x2, rect->y2); gint x1 = MAX (rect.x1 * zm + 0.5, 0); gint x2 = MAX (rect.x2 * zm - 0.5, 1); gint y1 = MAX ((iy - rect.y2 * zm) + 0.5, 0); gint y2 = MAX ((iy - rect.y1 * zm) - 0.5, 1); //debug ("x1: %d, y1: %d, x2: %d, y2: %d", x1, y1, x2, y2); // heightlight the selection for (gint y = y1; y < y2; y++) { for (gint x = x1; x < x2; x++) { gint p = (gint) (y * ix * 3 + (x * 3)); buffer[p + 0] = 0xff - buffer[p + 0]; buffer[p + 1] = 0xff - buffer[p + 0]; buffer[p + 2] = 0xff - buffer[p + 0]; } } // change the back color of the selection for (ApvlvPoses::const_iterator itr = poses->begin (); itr != poses->end (); itr++) { // Caculate the correct position x1 = (gint) (itr->x1 * zm); x2 = (gint) (itr->x2 * zm); y1 = (gint) (iy - itr->y2 * zm); y2 = (gint) (iy - itr->y1 * zm); for (gint y = y1; y < y2; y++) { for (gint x = x1; x < x2; x++) { gint p = (gint) (y * 3 * ix + (x * 3)); buffer[p + 0] = 0xff - buffer[p + 0]; buffer[p + 1] = 0xff - buffer[p + 0]; buffer[p + 2] = 0xff - buffer[p + 0]; } } } return true; } ApvlvLinks *ApvlvPDF::getlinks (int pn) { PopplerPage *page = poppler_document_get_page (mDoc, pn); GList *list = poppler_page_get_link_mapping (page); if (list == NULL) { return NULL; } ApvlvLinks *links = new ApvlvLinks; for (GList * tmp = list; tmp != NULL; tmp = g_list_next (tmp)) { PopplerLinkMapping *map = (PopplerLinkMapping *) tmp->data; if (map) { PopplerAction *act = map->action; if (act && *(PopplerActionType *) act == POPPLER_ACTION_GOTO_DEST) { PopplerDest *pd = ((PopplerActionGotoDest *) act)->dest; if (pd->type == POPPLER_DEST_NAMED) { PopplerDest *destnew = poppler_document_find_dest (mDoc, pd->named_dest); if (destnew != NULL) { ApvlvLink link = { "", destnew->page_num - 1 }; links->insert (links->begin (), link); poppler_dest_free (destnew); } } else { ApvlvLink link = { "", pd->page_num - 1 }; links->insert (links->begin (), link); } } } } return links; } ApvlvFileIndex *ApvlvPDF::new_index () { if (mIndex != NULL) { debug ("file %p has index: %p, return", this, mIndex); return mIndex; } PopplerIndexIter *itr = poppler_index_iter_new (mDoc); if (itr == NULL) { debug ("no index."); return NULL; } mIndex = new ApvlvFileIndex; walk_poppler_index_iter (mIndex, itr); poppler_index_iter_free (itr); return mIndex; } void ApvlvPDF::free_index (ApvlvFileIndex * index) { delete index; } bool ApvlvPDF::walk_poppler_index_iter (ApvlvFileIndex * titr, PopplerIndexIter * iter) { bool has = false; do { has = false; ApvlvFileIndex *index = NULL; PopplerAction *act = poppler_index_iter_get_action (iter); if (act) { if (*(PopplerActionType *) act == POPPLER_ACTION_GOTO_DEST) { PopplerActionGotoDest *pagd = (PopplerActionGotoDest *) act; if (pagd->dest->type == POPPLER_DEST_NAMED) { PopplerDest *destnew = poppler_document_find_dest (mDoc, pagd-> dest-> named_dest); int pn = 1; if (destnew != NULL) { pn = destnew->page_num - 1; poppler_dest_free (destnew); } index = new ApvlvFileIndex; index->page = pn; } else { index = new ApvlvFileIndex; index->page = pagd->dest->page_num - 1; } if (index != NULL) { has = true; index->title = pagd->title; titr->children.push_back (*index); delete index; index = &(titr->children[titr->children.size () - 1]); debug ("titr: %p, index: %p", titr, index); } } poppler_action_free (act); } PopplerIndexIter *child = poppler_index_iter_get_child (iter); if (child) { bool chas = walk_poppler_index_iter (has ? index : titr, child); has = has ? has : chas; poppler_index_iter_free (child); } } while (poppler_index_iter_next (iter)); return has; } bool ApvlvPDF::pageprint (int pn, cairo_t * cr) { #ifdef WIN32 return false; #else PopplerPage *page = poppler_document_get_page (mDoc, pn); if (page != NULL) { poppler_page_render_for_printing (page, cr); return true; } else { return false; } #endif } #ifdef HAVE_LIBDJVU void handle_ddjvu_messages (ddjvu_context_t * ctx, int wait) { const ddjvu_message_t *msg; if (wait) ddjvu_message_wait (ctx); while ((msg = ddjvu_message_peek (ctx))) { debug ("tag: %d", msg->m_any.tag); switch (msg->m_any.tag) { case DDJVU_ERROR: break; case DDJVU_INFO: break; case DDJVU_PAGEINFO: break; default: break; } ddjvu_message_pop (ctx); } } #endif ApvlvDJVU::ApvlvDJVU (const char *filename, bool check):ApvlvFile (filename, check) { #ifdef HAVE_LIBDJVU mContext = ddjvu_context_create ("apvlv"); if (mContext) { mDoc = ddjvu_document_create_by_filename (mContext, filename, FALSE); } if (mDoc != NULL) { if (ddjvu_document_get_type (mDoc) == DDJVU_DOCTYPE_SINGLEPAGE) { debug ("djvu type: %d", ddjvu_document_get_type (mDoc)); } else { /* ddjvu_document_release (mDoc); mDoc = NULL; ddjvu_context_release (mContext); mContext = NULL; throw std::bad_alloc (); */ } } else { ddjvu_context_release (mContext); mContext = NULL; throw std::bad_alloc (); } #else throw std::bad_alloc (); #endif } ApvlvDJVU::~ApvlvDJVU () { #ifdef HAVE_LIBDJVU if (mContext) { ddjvu_context_release (mContext); } if (mDoc) { ddjvu_document_release (mDoc); } #endif } bool ApvlvDJVU::writefile (const char *filename) { #ifdef HAVE_LIBDJVU FILE *fp = fopen (filename, "wb"); if (fp != NULL) { ddjvu_job_t *job = ddjvu_document_save (mDoc, fp, 0, NULL); while (!ddjvu_job_done (job)) { handle_ddjvu_messages (mContext, TRUE); } fclose (fp); return true; } return false; #else return false; #endif } bool ApvlvDJVU::pagesize (int pn, int rot, double *x, double *y) { #ifdef HAVE_LIBDJVU ddjvu_status_t t; ddjvu_pageinfo_t info[1]; while ((t = ddjvu_document_get_pageinfo (mDoc, 0, info)) < DDJVU_JOB_OK) { handle_ddjvu_messages (mContext, true); } if (t == DDJVU_JOB_OK) { *x = info->width; *y = info->height; debug ("djvu page 1: %f-%f", *x, *y); } return true; #else return false; #endif } int ApvlvDJVU::pagesum () { #ifdef HAVE_LIBDJVU return mDoc ? ddjvu_document_get_pagenum (mDoc) : 0; #else return 0; #endif } bool ApvlvDJVU::render (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer) { #ifdef HAVE_LIBDJVU ddjvu_page_t *tpage; if ((tpage = ddjvu_page_create_by_pageno (mDoc, pn)) == NULL) { debug ("no this page: %d", pn); return false; } ddjvu_rect_t prect[1] = { {0, 0, ix, iy} }; ddjvu_rect_t rrect[1] = { {0, 0, ix, iy} }; ddjvu_format_t *format = ddjvu_format_create (DDJVU_FORMAT_RGB24, 0, NULL); ddjvu_format_set_row_order (format, TRUE); gint retry = 0; while (retry <= 20 && ddjvu_page_render (tpage, DDJVU_RENDER_COLOR, prect, rrect, format, 3 * ix, (char *) buffer) == FALSE) { usleep (50 * 1000); debug ("fender failed, retry %d", ++retry); } return true; #else return false; #endif } bool ApvlvDJVU::pageselectsearch (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer, int sel, ApvlvPoses * poses) { return false; } ApvlvPoses *ApvlvDJVU::pagesearch (int pn, const char *str, bool reverse) { return NULL; } ApvlvLinks *ApvlvDJVU::getlinks (int pn) { return NULL; } bool ApvlvDJVU::pagetext (int pn, int x1, int y1, int x2, int y2, char **out) { return false; } ApvlvFileIndex *ApvlvDJVU::new_index () { return NULL; } void ApvlvDJVU::free_index (ApvlvFileIndex * index) { } bool ApvlvDJVU::pageprint (int pn, cairo_t * cr) { return false; } ApvlvUMD::ApvlvUMD (const char *filename, bool check):ApvlvFile (filename, check) { #ifdef HAVE_LIBUMD gchar * lname = g_locale_from_utf8 (filename, -1, NULL, NULL, NULL); if (lname) { mUmd = umd_new_from_file (lname); g_free (lname); } else { mUmd = umd_new_from_file (filename); } if (mUmd == NULL) { throw std::bad_alloc (); } #else throw std::bad_alloc (); #endif } ApvlvUMD::~ApvlvUMD () { #ifdef HAVE_LIBUMD if (mUmd) { umd_destroy (mUmd); } #endif } bool ApvlvUMD::writefile (const char *filename) { #ifdef HAVE_LIBUMD if (umd_write_file (mUmd, filename) == 0) { return true; } return false; #else return false; #endif } bool ApvlvUMD::pagesize (int pn, int rot, double *x, double *y) { #ifdef HAVE_LIBUMD umd_page_t * page; page = umd_get_nth_page (mUmd, pn); if (page) { int ix, iy; umd_page_get_size (page, &ix, &iy); *x = ix; *y = iy; return true; } return false; #else return false; #endif } int ApvlvUMD::pagesum () { #ifdef HAVE_LIBUMD return mUmd ? umd_get_page_n (mUmd) : 0; #else return 0; #endif } bool ApvlvUMD::render (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer) { #ifdef HAVE_LIBUMD umd_page_t * page; page = umd_get_nth_page (mUmd, pn); if (page) { umd_page_render (page, 0, 0, ix, iy, zm, rot, (unsigned char *) buffer, 3 * ix); return true; } return false; #else return false; #endif } bool ApvlvUMD::pageselectsearch (int pn, int ix, int iy, double zm, int rot, GdkPixbuf * pix, char *buffer, int sel, ApvlvPoses * poses) { return false; } ApvlvPoses *ApvlvUMD::pagesearch (int pn, const char *str, bool reverse) { return NULL; } ApvlvLinks *ApvlvUMD::getlinks (int pn) { return NULL; } bool ApvlvUMD::pagetext (int pn, int x1, int y1, int x2, int y2, char **out) { return false; } ApvlvFileIndex *ApvlvUMD::new_index () { #ifdef HAVE_LIBUMD if (mIndex != NULL) { debug ("file %p has index: %p, return", this, mIndex); return mIndex; } int cpt_n = umd_get_chapter_n (mUmd); if (cpt_n <= 0) { debug ("no index."); return NULL; } mIndex = new ApvlvFileIndex; for (int i = 0; i < cpt_n; ++ i) { umd_chapter_t * chapter = umd_get_nth_chapter (mUmd, i); if (chapter) { ApvlvFileIndex inx; inx.title = chapter->title; inx.page = chapter->page_index; mIndex->children.push_back (inx); free (chapter->title); free (chapter->content); free (chapter); } } return mIndex; #else return NULL; #endif } void ApvlvUMD::free_index (ApvlvFileIndex * index) { #ifdef HAVE_LIBUMD delete mIndex; #endif } bool ApvlvUMD::pageprint (int pn, cairo_t * cr) { return false; } } apvlv-0.1.1-Source/src/ApvlvInfo.cpp100644 1750 1750 11267 11521211167 16401 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvInfo.cpp * * Author: Alf */ /* @date Created: 2010/02/23 15:00:42 Alf*/ #include "ApvlvInfo.hpp" #include #include #include #include namespace apvlv { ApvlvInfo *gInfo = NULL; ApvlvInfo::ApvlvInfo (const char *filename) { mFileName = filename; mFileHead = NULL; mFileMax = 10; ifstream is (mFileName.c_str (), ios::in); if (is.is_open ()) { string line; const char *p; while (getline (is, line)) { p = line.c_str (); if (*p != '\'' /* the ' */ || !isdigit (*(p + 1))) /* the digit */ { continue; } ini_add_position (p); } mFileHead = g_slist_reverse (mFileHead); is.close (); } } ApvlvInfo::~ApvlvInfo () { for (GSList *list = mFileHead; list != NULL; list = g_slist_next (list)) { infofile *fp = (infofile *) (list->data); delete fp; } g_slist_free (mFileHead); } bool ApvlvInfo::update () { ofstream os (mFileName.c_str (), ios::out); if (!os.is_open ()) { return false; } int i; GSList *lfp; infofile *fp; for (i = 0, lfp = mFileHead; i < mFileMax && lfp != NULL; ++i, lfp = g_slist_next (lfp)) { fp = (infofile *) (lfp->data); if (fp) { os << "'" << i << "\t"; os << fp->page << ':' << fp->skip << "\t"; os << fp->rate << "\t"; os << fp->file << endl; } } os.close (); return true; } infofile *ApvlvInfo::file (int id) { infofile *fp = (infofile *) g_slist_nth_data (mFileHead, id); return fp; } infofile *ApvlvInfo::file (const char *filename) { GSList *lfp; infofile *fp; for (lfp = mFileHead; lfp != NULL; lfp = g_slist_next (lfp)) { fp = (infofile *) (lfp->data); if (fp->file == filename) { break; } } if (lfp == NULL) { fp = new infofile; fp->page = 0; fp->skip = 0; fp->rate = 0.0; fp->file = filename; mFileHead = g_slist_insert_before (mFileHead, mFileHead, fp); } else { mFileHead = g_slist_remove (mFileHead, fp); mFileHead = g_slist_insert_before (mFileHead, mFileHead, fp); } return fp; } bool ApvlvInfo::file (int page, double rate, const char *filename, int skip) { infofile *fp; fp = file (filename); if (fp == NULL) { return false; } fp->page = page; fp->rate = rate; fp->skip = skip; update (); return true; } bool ApvlvInfo::ini_add_position (const char *str) { const char *p, *s; p = strchr (str + 2, '\t'); /* Skip the ' and the digit */ if (p == NULL) { return false; } while (*p != '\0' && !isdigit (*p)) { p++; } int page = atoi (p); int skip; s = strchr (p, ':'); for (;s && p < s; ++p) { if (!isdigit (*p)) { break; } } if (p == s) { ++ p; skip = atoi (p); } else { skip = 0; } p = strchr (p, '\t'); if (p == NULL) { return false; } while (*p != '\0' && !isdigit (*p)) { p++; } double rate = atof (p); p = strchr (p, '\t'); if (p == NULL) { return false; } while (*p != '\0' && isspace (*p)) { p++; } if (*p == '\0') { return false; } infofile *fp = new infofile; fp->page = page; fp->rate = rate; fp->skip = skip; fp->file = p; mFileHead = g_slist_insert_before (mFileHead, mFileHead, fp); return true; } }; apvlv-0.1.1-Source/src/ApvlvDir.cpp100644 1750 1750 52635 11521211167 16230 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CFILE ApvlvDir.cpp * * Author: Alf */ /* @date Created: 2009/01/03 23:28:26 Alf*/ #include "ApvlvView.hpp" #include "ApvlvParams.hpp" #include "ApvlvDir.hpp" #include #include #include #include #include #include #include #include namespace apvlv { ApvlvDirNode::ApvlvDirNode (GtkTreeIter * ir, gint p) { *itr = *ir; mPagenum = p; realname = NULL; } ApvlvDirNode::ApvlvDirNode (GtkTreeIter * ir, bool isdir, const char *real, const char *file) { *itr = *ir; mPagenum = isdir ? -1 : 0; g_snprintf (filename, sizeof filename, "%s", file); realname = g_strdup (real); } ApvlvDirNode::~ApvlvDirNode () { if (realname) { g_free (realname); } } bool ApvlvDirNode::dest (const char **path, int *pn) { if (mPagenum == 0 && path != NULL) { *path = realname; return true; } else if (mPagenum > 0 && pn != NULL) { *pn = mPagenum; return true; } return false; } const char *ApvlvDirNode::phrase () { return filename; } const GtkTreeIter *ApvlvDirNode::iter () { return itr; } ApvlvDir::ApvlvDir (int w, int h) { mReady = false; mProCmd = 0; mRotatevalue = 0; mDirNodes = NULL; mIndex = NULL; mFile = NULL; mStore = gtk_tree_store_new (3, G_TYPE_POINTER, G_TYPE_OBJECT, G_TYPE_STRING); mDirView = gtk_tree_view_new_with_model (GTK_TREE_MODEL (mStore)); gtk_container_add (GTK_CONTAINER (mScrollwin), mDirView); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (mDirView), FALSE); mSelection = gtk_tree_view_get_selection (GTK_TREE_VIEW (mDirView)); g_signal_connect (G_OBJECT (mSelection), "changed", G_CALLBACK (apvlv_dir_on_changed), this); /* Title Column */ GtkCellRenderer *renderer0 = gtk_cell_renderer_pixbuf_new (); GtkCellRenderer *renderer = gtk_cell_renderer_text_new (); GtkTreeViewColumn *column = gtk_tree_view_column_new (); gtk_tree_view_column_pack_start (column, renderer0, FALSE); gtk_tree_view_column_pack_start (column, renderer, FALSE); gtk_tree_view_column_add_attribute (column, renderer0, "pixbuf", 1); gtk_tree_view_column_add_attribute (column, renderer, "text", 2); gtk_tree_view_column_set_sort_column_id (column, 2); gtk_tree_view_append_column (GTK_TREE_VIEW (mDirView), column); mStatus = new ApvlvDirStatus (this); gtk_box_pack_start (GTK_BOX (mVbox), mScrollwin, FALSE, FALSE, 0); gtk_box_pack_end (GTK_BOX (mVbox), mStatus->widget (), FALSE, FALSE, 0); gtk_widget_show_all (mVbox); setsize (w, h); } bool ApvlvDir::reload () { gtk_tree_store_clear (mStore); if (mDirNodes) { for (GList * list = mDirNodes; list; list = g_list_next (list)) { ApvlvDirNode *info = (ApvlvDirNode *) list->data; delete info; } g_list_free (mDirNodes); mDirNodes = NULL; } if (mIndex != NULL) { mFile->free_index (mIndex); mIndex = NULL; } if (mFile != NULL) { delete mFile; mFile = NULL; } loadfile (mFilestr.c_str (), FALSE); return true; } bool ApvlvDir::loadfile (const char *path, bool check) { gchar *rpath; if (path == NULL || *path == '\0' || (rpath = g_locale_from_utf8 (path, -1, NULL, NULL, NULL)) == NULL) { gView->errormessage ("path error: %s", path ? path : "No path"); return false; } struct stat buf[1]; int ret = stat (rpath, buf); g_free (rpath); if (ret < 0) { gView->errormessage ("stat error: %d:%s", errno, strerror (errno)); return false; } if (S_ISDIR (buf->st_mode)) { mReady = walk_dir_path_index (NULL, path); } else { mFile = ApvlvFile::newfile (path); if (mFile != NULL && (mIndex = mFile->new_index ()) != NULL) { for (ApvlvFileIndexIter itr = mIndex->children.begin (); itr != mIndex->children.end (); ++itr) { bool ready = walk_file_index (NULL, itr); if (mReady == false) { mReady = ready; } } } else { mReady = false; } } if (mReady) { mFilestr = path; mFirstSelTimer = g_timeout_add (50, (gboolean (*)(gpointer)) apvlv_dir_first_select_cb, this); } return mReady; } ApvlvDir::~ApvlvDir () { if (mDirNodes) { for (GList * list = mDirNodes; list; list = g_list_next (list)) { ApvlvDirNode *info = (ApvlvDirNode *) list->data; delete info; } g_list_free (mDirNodes); } if (mIndex != NULL) { mFile->free_index (mIndex); } if (mFile != NULL) { delete mFile; } delete mStatus; } returnType ApvlvDir::subprocess (int ct, guint key) { guint procmd = mProCmd; mProCmd = 0; switch (procmd) { default: return NO_MATCH; break; } return MATCH; } returnType ApvlvDir::process (int has, int ct, guint key) { if (ct == 0) { ct++; } if (mProCmd != 0) { return subprocess (ct, key); } switch (key) { case ':': case '/': case '?': gView->promptcommand (key); return NEED_MORE; case 'n': markposition ('\''); search (""); break; case 'N': markposition ('\''); search ("", true); break; case 't': case 'o': case GDK_Return: enter (key); break; case 'H': scrollto (0.0); break; case 'M': scrollto (0.5); break; case 'L': scrollto (1.0); break; case GDK_Up: case 'k': scrollup (ct); break; case CTRL ('n'): case CTRL ('j'): case GDK_Down: case 'j': scrolldown (ct); break; case GDK_BackSpace: case GDK_Left: case CTRL ('h'): case 'h': scrollleft (ct); break; case GDK_space: case GDK_Right: case CTRL ('l'): case 'l': scrollright (ct); break; case 'R': reload (); break; } return MATCH; } bool ApvlvDir::enter (guint key) { ApvlvDirNode *node; gtk_tree_model_get (GTK_TREE_MODEL (mStore), &mCurrentIter, 0, &node, -1); if (node == NULL) { return false; } const char *name = NULL; int pn = -1; if (!node->dest (&name, &pn)) { return false; } ApvlvCore *ndoc = NULL; if (name != NULL) { if (gParams->valueb ("content")) { ndoc = new ApvlvDir (mWidth, mHeight); if (!ndoc->loadfile (name)) { delete ndoc; ndoc = NULL; } } if (ndoc == NULL) { ndoc = new ApvlvDoc (mWidth, mHeight, gParams->values ("zoom"), gParams->valueb ("cache")); if (!ndoc->loadfile (name)) { delete ndoc; ndoc = NULL; } } } else { ndoc = new ApvlvDoc (mWidth, mHeight, gParams->values ("zoom"), gParams->valueb ("cache")); if (!ndoc->loadfile (filename ())) { delete ndoc; ndoc = NULL; } if (ndoc != NULL) { ((ApvlvDoc *) ndoc)->showpage (pn); } } if (ndoc == NULL) { return false; } gView->regloaded (ndoc); switch (key) { case GDK_Return: ApvlvWindow::currentWindow ()->setCore (ndoc); break; case 'o': ApvlvWindow::currentWindow ()->birth (false, ndoc); break; case 't': gView->newtab (ndoc); break; default: return false; } return true; } void ApvlvDir::scrollup (int times) { GtkTreePath *path; if (!mReady || (path = gtk_tree_model_get_path (GTK_TREE_MODEL (mStore), &mCurrentIter)) == NULL) { return; } for (gboolean ret = TRUE; times > 0 && ret; times--) { ret = gtk_tree_path_prev (path); } gtk_tree_model_get_iter (GTK_TREE_MODEL (mStore), &mCurrentIter, path); gtk_tree_selection_select_iter (mSelection, &mCurrentIter); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (mDirView), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free (path); mStatus->show (); } void ApvlvDir::scrolldown (int times) { if (!mReady) return; GtkTreeIter itr; gboolean ret; for (ret = TRUE, itr = mCurrentIter; times > 0 && ret; times--) { mCurrentIter = itr; ret = gtk_tree_model_iter_next (GTK_TREE_MODEL (mStore), &itr); if (ret) { mCurrentIter = itr; } } gtk_tree_selection_select_iter (mSelection, &mCurrentIter); GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (mStore), &mCurrentIter); if (path) { gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (mDirView), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free (path); } mStatus->show (); } void ApvlvDir::scrollleft (int times) { if (!mReady) return; GtkTreeIter itr; for (gboolean ret = TRUE; times > 0 && ret; times--) { ret = gtk_tree_model_iter_parent (GTK_TREE_MODEL (mStore), &itr, &mCurrentIter); if (ret) { mCurrentIter = itr; } } gtk_tree_selection_select_iter (mSelection, &mCurrentIter); GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (mStore), &mCurrentIter); if (path) { gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (mDirView), path, NULL, TRUE, 0.5, 0.0); gtk_tree_view_collapse_row (GTK_TREE_VIEW (mDirView), path); gtk_tree_path_free (path); } mStatus->show (); } void ApvlvDir::scrollright (int times) { if (!mReady) return; GtkTreeIter itr; for (gboolean ret = TRUE; times > 0 && ret; times--) { ret = gtk_tree_model_iter_children (GTK_TREE_MODEL (mStore), &itr, &mCurrentIter); if (ret) { mCurrentIter = itr; } } GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (mStore), &mCurrentIter); if (path) { gtk_tree_view_expand_to_path (GTK_TREE_VIEW (mDirView), path); gtk_tree_selection_select_iter (mSelection, &mCurrentIter); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (mDirView), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free (path); } mStatus->show (); } bool ApvlvDir::search (const char *str, bool reverse) { bool next; if (!mReady) return false; if (*str == '\0' && mSearchStr == "") { return false; } next = true; if (*str != '\0') { mSearchStr = str; next = false; } ApvlvDirNode *info = NULL; gtk_tree_model_get (GTK_TREE_MODEL (mStore), &mCurrentIter, 0, &info, -1); if (info == NULL || mDirNodes == NULL) { gView->errormessage ("can't find word: '%s'", mSearchStr.c_str ()); return false; } GList *list; for (list = mDirNodes; list; list = g_list_next (list)) { if (info == list->data) { break; } } if (list == NULL) { gView->errormessage ("can't find word: '%s'", mSearchStr.c_str ()); return false; } if (next) { if (reverse) { list = g_list_previous (list); } else { list = g_list_next (list); } } bool wrap = gParams->valueb ("wrapscan"); for (GList * origin = list; list != NULL;) { info = (ApvlvDirNode *) list->data; if (strstr (info->phrase (), mSearchStr.c_str ()) != NULL) { break; } if (reverse) { list = g_list_previous (list); } else { list = g_list_next (list); } if (list == origin) { list = NULL; break; } if (list == NULL && wrap) { if (reverse) { list = g_list_last (mDirNodes); } else { list = mDirNodes; } } } if (list == NULL) { gView->errormessage ("can't find word: '%s'", mSearchStr.c_str ()); return false; } mCurrentIter = *info->iter (); GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (mStore), &mCurrentIter); if (path) { gtk_tree_view_expand_to_path (GTK_TREE_VIEW (mDirView), path); gtk_tree_selection_select_iter (mSelection, &mCurrentIter); gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (mDirView), path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free (path); } mStatus->show (); return true; } void ApvlvDir::setactive (bool act) { mStatus->active (act); mActive = act; } bool ApvlvDir::walk_file_index (GtkTreeIter * titr, ApvlvFileIndexIter iter) { bool has = false; GtkTreeIter nitr[1]; has = true; gtk_tree_store_append (mStore, nitr, titr); ApvlvDirNode *node = new ApvlvDirNode (nitr, iter->page); mDirNodes = g_list_append (mDirNodes, node); GdkPixbuf *pix = gdk_pixbuf_new_from_file_at_size (iconreg.c_str (), 40, 20, NULL); if (pix) { gtk_tree_store_set (mStore, nitr, 0, node, 1, pix, 2, iter->title.c_str (), -1); g_object_unref (pix); } else { gtk_tree_store_set (mStore, nitr, 0, node, 2, iter->title.c_str (), -1); } for (ApvlvFileIndexIter itr = iter->children.begin (); itr != iter->children.end (); ++itr) { bool chas = walk_file_index (has ? nitr : titr, itr); if (has == false) { has = chas; } } return has; } void ApvlvDir::apvlv_dir_on_changed (GtkTreeSelection * selection, ApvlvDir * dir) { GtkTreeModel *model; gtk_tree_selection_get_selected (selection, &model, &dir->mCurrentIter); } ApvlvDirStatus::ApvlvDirStatus (ApvlvDir * doc) { mDoc = doc; for (int i = 0; i < AD_STATUS_SIZE; ++i) { mStlab[i] = gtk_label_new (""); gtk_box_pack_start (GTK_BOX (mHbox), mStlab[i], FALSE, FALSE, 0); } } ApvlvDirStatus::~ApvlvDirStatus () { } void ApvlvDirStatus::active (bool act) { for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_widget_modify_fg (mStlab[i], (act) ? GTK_STATE_ACTIVE : GTK_STATE_INSENSITIVE, NULL); } } void ApvlvDirStatus::setsize (int w, int h) { int sw[AD_STATUS_SIZE]; sw[0] = w >> 1; sw[1] = sw[0] >> 1; sw[2] = sw[1] >> 1; sw[3] = sw[1] >> 1; for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_widget_set_size_request (mStlab[i], sw[i], h); } } void ApvlvDirStatus::show () { if (mDoc->filename ()) { char temp[AD_STATUS_SIZE][256]; gchar *bn; bn = g_path_get_basename (mDoc->filename ()); g_snprintf (temp[0], sizeof temp[0], "%s", bn); g_snprintf (temp[1], sizeof temp[1], "apvlv"); g_snprintf (temp[2], sizeof temp[2], "%d%%", (int) (mDoc->zoomvalue () * 100)); g_snprintf (temp[3], sizeof temp[3], "%d%%", (int) (mDoc->scrollrate () * 100)); for (unsigned int i = 0; i < AD_STATUS_SIZE; ++i) { gtk_label_set_text (GTK_LABEL (mStlab[i]), temp[i]); } g_free (bn); } } gboolean ApvlvDir::apvlv_dir_first_select_cb (ApvlvDir * dir) { GtkTreeIter gtir; if (gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dir->mStore), >ir)) { gtk_tree_selection_select_iter (dir->mSelection, >ir); } return FALSE; } bool ApvlvDir::walk_dir_path_index (GtkTreeIter * itr, const char *path) { bool has = false; GDir *dir = g_dir_open (path, 0, NULL); if (dir != NULL) { const gchar *name; while ((name = g_dir_read_name (dir)) != NULL) { if (strcmp (name, ".") == 0) { debug ("avoid hidden file: %s", name); continue; } gchar *realname = g_strjoin (PATH_SEP_S, path, name, NULL); // debug ("add a item: %s[%s]", name, realname); ApvlvDirNode *node = NULL; struct stat buf[1]; char *wrealname = g_locale_from_utf8 (realname, -1, NULL, NULL, NULL); if (wrealname == NULL) { g_free (realname); continue; } int ret = stat (wrealname, buf); g_free (wrealname); if (ret < 0) { g_free (realname); continue; } if (S_ISDIR (buf->st_mode)) { GtkTreeIter mitr[1]; gtk_tree_store_append (mStore, mitr, itr); node = new ApvlvDirNode (mitr, true, realname, name); GdkPixbuf *pix = gdk_pixbuf_new_from_file_at_size (icondir.c_str (), 40, 20, NULL); if (pix) { gtk_tree_store_set (mStore, mitr, 0, node, 1, pix, 2, name, -1); g_object_unref (pix); } else { gtk_tree_store_set (mStore, mitr, 0, node, 2, name, -1); } if (!walk_dir_path_index (mitr, realname)) { gtk_tree_store_remove (mStore, mitr); delete node; node = NULL; } if (node != NULL) { mDirNodes = g_list_append (mDirNodes, node); has = true; } } else if (g_ascii_strncasecmp (name + strlen (name) - 4, ".pdf", 4) == 0 #ifdef HAVE_LIBUMD || g_ascii_strncasecmp (name + strlen (name) - 5, ".djvu", 5) == 0 || g_ascii_strncasecmp (name + strlen (name) - 4, ".djv", 4) == 0 #endif #ifdef HAVE_LIBUMD || g_ascii_strncasecmp (name + strlen (name) - 4, ".umd", 4) == 0 #endif ) { GtkTreeIter mitr[1]; gtk_tree_store_append (mStore, mitr, itr); node = new ApvlvDirNode (mitr, false, realname, name); mDirNodes = g_list_append (mDirNodes, node); GdkPixbuf *pix = gdk_pixbuf_new_from_file_at_size (iconpdf.c_str (), 40, 20, NULL); if (pix) { gtk_tree_store_set (mStore, mitr, 0, node, 1, pix, 2, name, -1); g_object_unref (pix); } else { gtk_tree_store_set (mStore, mitr, 0, node, 2, name, -1); } has = true; } g_free (realname); } } g_dir_close (dir); return has; } } apvlv-0.1.1-Source/src/ApvlvDoc.hpp100644 1750 1750 14550 11521211167 16216 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @PPCFILE ApvlvDoc.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_DOC_H_ #define _APVLV_DOC_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvFile.hpp" #include "ApvlvCore.hpp" #include "ApvlvUtil.hpp" #include //#include #include #include #include #include using namespace std; namespace apvlv { struct PrintData { ApvlvFile *file; guint frmpn, endpn; }; struct ApvlvDocPosition { int pagenum; double scrollrate; }; typedef map < char, ApvlvDocPosition > ApvlvDocPositionMap; struct ApvlvWord { ApvlvPos pos; string word; }; struct ApvlvLine { ApvlvPos pos; vector < ApvlvWord > mWords; }; class ApvlvDoc; class ApvlvDocCache { public: ApvlvDocCache (ApvlvFile *); ~ApvlvDocCache (); void set (guint p, double zm, guint rot, bool delay = true); static void load (ApvlvDocCache *); PopplerPage *getpage (); guint getpagenum (); guchar *getdata (bool wait); GdkPixbuf *getbuf (bool wait); double getwidth (); double getheight (); ApvlvLinks *getlinks (); bool canselect (); bool mInverted; ApvlvWord *getword (int x, int y); ApvlvLine *getline (double x, double y); private: ApvlvFile * mFile; ApvlvLinks *mLinks; double mZoom; double mRotate; gint mPagenum; guchar *mData; gint mSize; GdkPixbuf *mBuf; gint mWidth; gint mHeight; vector < ApvlvLine > *mLines; void preparelines (double x1, double y1, double x2, double y2); ApvlvPos prepare_add (ApvlvPos & last, ApvlvPoses * results, const char *word); }; class ApvlvDocStatus:public ApvlvCoreStatus { public: ApvlvDocStatus (ApvlvDoc *); ~ApvlvDocStatus (); void active (bool act); void setsize (int, int); void show (); private: ApvlvDoc * mDoc; #define AD_STATUS_SIZE 4 GtkWidget *mStlab[AD_STATUS_SIZE]; }; class ApvlvDoc:public ApvlvCore { public: ApvlvDoc (int w, int h, const char *zm = "NORMAL", bool cache = false); ~ApvlvDoc (); void setactive (bool act); ApvlvDoc *copy (); bool usecache (); void usecache (bool use); bool loadfile (string & filename, bool check = true); bool loadfile (const char *src, bool check = true); int pagenumber (); bool print (int ct); bool totext (const char *name); bool rotate (int ct = 90); void markposition (const char s); void setzoom (const char *z); void jump (const char s); void showpage (int p, double s = 0.00); void nextpage (int times = 1); void prepage (int times = 1); void halfnextpage (int times = 1); void halfprepage (int times = 1); void scrollup (int times); void scrolldown (int times); void scrollleft (int times); void scrollright (int times); bool search (const char *str, bool reverse = false); bool continuous (); returnType process (int hastimes, int times, guint keyval); void gotolink (int ct); void returnlink (int ct); private: void blank (int x, int y); void blankarea (int x1, int y1, int x2, int y2, guchar *, int width, int height); void blankaction (double x, double y); void togglevisual (int type); int yank (int times); void eventpos (double x, double y, double *rx, double *ry); returnType subprocess (int ct, guint key); bool status_show (); int convertindex (int p); void markselection (); bool needsearch (const char *str, bool reverse = false); void refresh (); bool reload (); bool savelastposition (const char *filename); bool loadlastposition (const char *filename); static void apvlv_doc_on_mouse (GtkAdjustment *, ApvlvDoc *); static gboolean apvlv_doc_first_scroll_cb (gpointer); static gboolean apvlv_doc_first_copy_cb (gpointer); static void apvlv_doc_button_event (GtkEventBox * box, GdkEventButton * ev, ApvlvDoc *); static void apvlv_doc_motion_event (GtkWidget *, GdkEventMotion *, ApvlvDoc *); static void apvlv_doc_copytoclipboard_cb (GtkMenuItem * item, ApvlvDoc *); static void begin_print (GtkPrintOperation * operation, GtkPrintContext * context, PrintData * data); static void draw_page (GtkPrintOperation * operation, GtkPrintContext * context, gint page_nr, PrintData * data); static void end_print (GtkPrintOperation * operation, GtkPrintContext * context, PrintData * data); enum { VISUAL_NONE, VISUAL_V, VISUAL_CTRL_V }; gint mInVisual; gint mBlankx1, mBlanky1; gint mBlankx2, mBlanky2; gint mLastpress; gint mCurx, mCury; ApvlvDocPositionMap mPositions; vector < ApvlvDocPosition > mLinkPositions; ApvlvDocCache *mCurrentCache1, *mCurrentCache2; ApvlvDocCache *newcache (int pagenum); void deletecache (ApvlvDocCache * ac); bool mAutoScrollPage; bool mAutoScrollDoc; bool mContinuous; // image viewer GtkWidget *mImage1, *mImage2; }; } #endif apvlv-0.1.1-Source/src/ApvlvParams.cpp100644 1750 1750 13327 11521211167 16730 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvParams.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvUtil.hpp" #include "ApvlvCmds.hpp" #include "ApvlvParams.hpp" #include #include #include namespace apvlv { ApvlvParams *gParams = NULL; ApvlvParams::ApvlvParams () { push ("inverted", "no"); push ("fullscreen", "no"); push ("zoom", "fitwidth"); push ("continuous", "yes"); push ("autoscrollpage", "yes"); push ("autoscrolldoc", "yes"); push ("continuouspad", "2"); push ("noinfo", "no"); push ("width", "800"); push ("height", "600"); push ("content", "yes"); push ("cache", "no"); push ("pdfcache", "4"); push ("scrollbar", "no"); push ("visualmode", "no"); push ("warpscan", "yes"); push ("commandtimeout", "1000"); push ("doubleclick", "page"); #ifdef WIN32 push ("defaultdir", "C:\\"); #else push ("defaultdir", "/tmp"); #endif push ("guioptions", ""); push ("autoreload", "3"); } ApvlvParams::~ApvlvParams () { mSettings.clear (); } bool ApvlvParams::loadfile (const char *filename) { if (filename == NULL || g_file_test (filename, G_FILE_TEST_IS_REGULAR) == FALSE) { return false; } // debug ("load debug: %s", filename); string str; fstream os (filename, ios::in); if (!os.is_open ()) { errp ("Open configure file %s error", filename); return false; } while ((getline (os, str)) != NULL) { string argu, data, crap; stringstream is (str); // avoid commet line, continue next is >> crap; if (crap[0] == '\"' || crap == "") { continue; } // parse the line like "set fullscreen=yes" or set "set zoom=1.5" else if (crap == "set") { is >> argu; size_t off = argu.find ('='); if (off == string::npos) { is >> crap >> data; if (crap == "=") { push (argu.c_str (), data.c_str ()); continue; } } else if (off < 32) { char k[32], v[32], *p; memcpy (k, argu.c_str (), off); k[off] = '\0'; p = (char *) argu.c_str () + off + 1; while (isspace (*p)) { p++; } g_snprintf (v, sizeof v, "%s", *p ? p : ""); p = (char *) v + strlen (v) - 1; while (isspace (*p) && p >= v) { p--; } *(p + 1) = '\0'; push (k, v); continue; } errp ("Syntax error: set: %s", str.c_str ()); } // like "map n next-page" else if (crap == "map") { is >> argu; if (argu.length () == 0) { errp ("map command not complete"); continue; } getline (is, data); while (data.length () > 0 && isspace (data[0])) data.erase (0, 1); if (argu.length () > 0 && data.length () > 0) { gCmds->buildmap (argu.c_str (), data.c_str ()); } else { errp ("Syntax error: map: %s", str.c_str ()); } } else { errp ("Unknown rc command: %s: %s", crap.c_str (), str.c_str ()); } } return true; } bool ApvlvParams::push (const char *c, const char *s) { string cs (c), ss (s); mSettings[cs] = ss; return true; } bool ApvlvParams::push (string & ch, string & str) { mSettings[ch] = str; return true; } const char *ApvlvParams::values (const char *s) { string ss (s); map < string, string >::iterator it; it = mSettings.find (ss); if (it != mSettings.end ()) { return it->second.c_str (); } return NULL; } int ApvlvParams::valuei (const char *s) { string ss (s); map < string, string >::iterator it; it = mSettings.find (ss); if (it != mSettings.end ()) { return atoi (it->second.c_str ()); } return -1; } double ApvlvParams::valuef (const char *s) { string ss (s); map < string, string >::iterator it; it = mSettings.find (ss); if (it != mSettings.end ()) { return atof (it->second.c_str ()); } return -1.0; } bool ApvlvParams::valueb (const char *s) { string ss (s); map < string, string >::iterator it; it = mSettings.find (ss); if (it != mSettings.end () && it->second.compare ("yes") == 0) { return true; } return false; } } apvlv-0.1.1-Source/src/ApvlvMenu.hpp100644 1750 1750 2413 11521211167 16370 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvMenu.hpp * * Author: Alf */ /* @date Created: 2010/01/21 15:09:25 Alf*/ #ifndef _APVLV_MENU_H_ #define _APVLV_MENU_H_ #ifdef HAVE_CONFIG_H #include "config.hpp" #endif #include namespace apvlv { class ApvlvView; class ApvlvMenu { public: ApvlvMenu (); ~ApvlvMenu (); GtkWidget *widget (); void setsize (gint, gint); private: GtkWidget * mMenu; }; }; #endif apvlv-0.1.1-Source/src/ApvlvView.hpp100644 1750 1750 11307 11521211167 16420 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvView.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_VIEW_H_ #define _APVLV_VIEW_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include "ApvlvMenu.hpp" #include "ApvlvDoc.hpp" #include "ApvlvWindow.hpp" #include #include #include namespace apvlv { typedef enum { SEARCH = '/', BACKSEARCH = '?', COMMANDMODE = ':' } cmd_mode_type; class ApvlvDoc; class ApvlvWindow; class ApvlvView { public: ApvlvView (const char *); ~ApvlvView (); void show (); GtkWidget *widget (); ApvlvWindow *currentWindow (); void delcurrentWindow (); bool newtab (const char *filename); bool newtab (ApvlvCore * core); void promptcommand (char ch); void promptcommand (const char *str); void errormessage (const char *str, ...); void infomessage (const char *str, ...); bool run (const char *str); bool loadfile (string file); bool loadfile (const char *filename); bool loaddir (const char *path); ApvlvCore *hasloaded (const char *filename, int type); void regloaded (ApvlvCore *); void open (); void opendir (); void close (); void quit (); void fullscreen (); returnType process (int hastimes, int times, guint keyval); returnType subprocess (int times, guint keyval); void cmd_show (int ct); void cmd_hide (); void cmd_auto (const char *); void settitle (const char *); ApvlvCore *crtadoc (); private: void refresh (); bool destroy; GCompletion *filecompleteinit (const char *s); bool runcmd (const char *cmd); int new_tabcontext (ApvlvCore * core, bool insertAfterCurr); void delete_tabcontext (int tabPos); void switch_tabcontext (int tabPos); // Caclulate number of pixels that the document should be. // This figure accounts for decorations like (mCmdBar and mHaveTabs). // Returns a nonnegative number. int adjheight (); void switchtab (int tabPos); // Update the tab's context and update tab label. void windowadded (); void updatetabname (); int mCmdType; guint mProCmd; GtkWidget *mMainWindow; ApvlvMenu *mMenu; GtkWidget *mViewBox; GtkWidget *mTabContainer; GtkWidget *mCommandBar; struct TabEntry { ApvlvWindow *root; ApvlvWindow *curr; int numwindows; TabEntry (ApvlvWindow * _r, ApvlvWindow * _c, int _n):root (_r), curr (_c), numwindows (_n) { } }; // possibly use GArray instead std::vector < TabEntry > mTabList; int mCurrTabPos; gboolean mHasFull; int mWidth, mHeight; static void apvlv_view_delete_cb (GtkWidget * wid, GtkAllocation * al, ApvlvView * view); static void apvlv_view_resized_cb (GtkWidget * wid, GtkAllocation * al, ApvlvView * view); static gint apvlv_view_keypress_cb (GtkWidget * wid, GdkEvent * ev, ApvlvView * view); static gint apvlv_view_commandbar_cb (GtkWidget * wid, GdkEvent * ev, ApvlvView * view); static void apvlv_notebook_switch_cb (GtkWidget * wid, GtkNotebookPage * page, guint num, ApvlvView * view); ApvlvWindow *mRootWindow; std::vector < ApvlvCore * >mDocs; std::vector < string > mCmdHistroy; int mCurrHistroy; bool mInHistroy; static const int APVLV_MENU_HEIGHT, APVLV_CMD_BAR_HEIGHT, APVLV_TABS_HEIGHT; }; extern ApvlvView *gView; } #endif apvlv-0.1.1-Source/src/ApvlvCmds.hpp100644 1750 1750 7035 11521211167 16357 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvCmds.hpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #ifndef _APVLV_CMDS_H_ #define _APVLV_CMDS_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include #include #include #include using namespace std; namespace apvlv { typedef enum { CT_CMD, CT_STRING, CT_STRING_RETURN } cmdType; typedef map < guint, const char *>KeyStringMap; typedef map < const char *, guint > StringKeyMap; class ApvlvCmd; typedef vector < guint > ApvlvCmdKeyv; typedef map < ApvlvCmdKeyv, ApvlvCmd * >ApvlvCmdMap; class ApvlvCmd { public: ApvlvCmd (); ~ApvlvCmd (); void process (); void push (const char *s, cmdType type = CT_CMD); bool append (GdkEventKey * key); const char *append (const char *s); bool cmp (ApvlvCmd & cmd); void type (cmdType type); cmdType type (); void bemap (bool bemap); bool bemap (); void canmap (bool canmap); bool canmap (); void hascount (bool hascount); bool hascount (); const char *c_str (); ApvlvCmdKeyv *keyvalv_p (); ApvlvCmdKeyv keyvalv (); void precount (gint precount); gint precount (); gint keyval (guint id); void next (ApvlvCmd * cmd); ApvlvCmd *next (); void origin (ApvlvCmd * cmd); ApvlvCmd *origin (); private: // command type cmdType mType; // if cmd is be mapped bool mBeMap; // if cmd can be mapped bool mCanMap; // if has count bool mHasPreCount; // how to descripe this command in .apvlvrc // like , s, or :run, :vsp, ... string mStrCommand; // key's value list ApvlvCmdKeyv mKeyVals; // cmd's pre count gint mPreCount; // next command ApvlvCmd *mNext; // when a key is map to other, this is the origin cmd. // after a maped key was processed, return to this cmds ApvlvCmd *mOrigin; }; class ApvlvCmds { public: ApvlvCmds (); ~ApvlvCmds (); void append (GdkEventKey * gev); bool buildmap (const char *os, const char *ms); private: ApvlvCmd * process (ApvlvCmd * cmd); returnType ismap (ApvlvCmdKeyv * ack); ApvlvCmd *getmap (const char *os); ApvlvCmd *getmap (ApvlvCmd * cmd); static gboolean apvlv_cmds_timeout_cb (gpointer); ApvlvCmdMap mMaps; ApvlvCmd *mCmdHead; enum cmdState { GETTING_COUNT, GETTING_CMD, CMD_OK, } mState; gint mTimeoutTimer; string mCountString; }; extern ApvlvCmds *gCmds; } #endif apvlv-0.1.1-Source/src/ApvlvCmds.cpp100644 1750 1750 26515 11521211167 16376 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvCmds.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvParams.hpp" #include "ApvlvView.hpp" #include "ApvlvUtil.hpp" #include "ApvlvCmds.hpp" #include #include #ifndef WIN32 #include #endif #include #include namespace apvlv { ApvlvCmds *gCmds = NULL; StringKeyMap SK; #define gek2guint(g) ((g)->state == GDK_CONTROL_MASK? CTRL ((g)->keyval): (g)->keyval) static inline bool modifierkey (guint k) { switch (k) { case GDK_Shift_L: case GDK_Shift_R: case GDK_Shift_Lock: case GDK_Meta_L: case GDK_Meta_R: case GDK_Alt_L: case GDK_Alt_R: case GDK_Super_L: case GDK_Super_R: case GDK_Hyper_L: case GDK_Hyper_R: case GDK_Control_L: case GDK_Control_R: return true; default: return false; } } ApvlvCmd::ApvlvCmd () { mType = CT_CMD; mBeMap = false; mCanMap = true; mHasPreCount = false; mPreCount = 1; mNext = NULL; mOrigin = NULL; } void ApvlvCmd::type (cmdType type) { mType = type; } cmdType ApvlvCmd::type () { return mType; } void ApvlvCmd::push (const char *s, cmdType type) { asst (s); mType = type; mHasPreCount = false; mPreCount = 1; mNext = NULL; if (isdigit (*s)) { mHasPreCount = true; mPreCount = atoi (s); do { s++; } while (isdigit (*s)); } if (*s == ':' || *s == '/' || *s == '?') { mStrCommand = s; mType = CT_STRING; size_t off = mStrCommand.find (""); if (off != string::npos) { mStrCommand.erase (off, mStrCommand.length () - off); mType = CT_STRING_RETURN; mNext = new ApvlvCmd; mNext->push (s + off + 4); } debug ("set string type command: [%s]", mStrCommand.c_str ()); return; } while (*s != '\0') { s = append (s); } } ApvlvCmd::~ApvlvCmd () { delete mNext; } void ApvlvCmd::process () { if (type () == CT_STRING) { gView->promptcommand (c_str ()); } else if (type () == CT_STRING_RETURN) { gView->run (c_str ()); } else { for (guint k = 0; k < keyvalv_p ()->size (); ++k) { gint key = keyval (k); if (key > 0) gView->process (mHasPreCount, precount (), keyval (k)); } } if (next () != NULL) { next ()->process (); } } bool ApvlvCmd::append (GdkEventKey * gek) { if (modifierkey (gek->keyval)) return false; if (gek->state & GDK_CONTROL_MASK) { mKeyVals.push_back (CTRL (gek->keyval)); } else { mKeyVals.push_back (gek->keyval); } return true; } const char *ApvlvCmd::append (const char *s) { size_t len; char *e; len = strlen (s); asst (len); if (len >= 4 && *s == '<' && (e = strchr ((char *) s, '>')) != '\0' && *(s + 2) != '-') { e++; StringKeyMap::iterator it; for (it = SK.begin (); it != SK.end (); it++) { if (strncmp (it->first, s, e - s) == 0) { mKeyVals.push_back (it->second); return e; } } } if (len >= 5 && s[0] == '<' && s[2] == '-' && s[4] == '>') { if (s[1] == 'C') { mKeyVals.push_back (CTRL (s[3])); } /* commet as above else if (s[1] == 'S') { mKeyVals.push_back (SHIFT (s[3])); } */ else { char ts[6]; g_snprintf (ts, 6, "%s", s); gView->errormessage ("Can't recognize the symbol: %s", ts); } return s + 5; } else { mKeyVals.push_back (s[0]); return s + 1; } return s; } void ApvlvCmd::bemap (bool bemap) { mBeMap = bemap; } bool ApvlvCmd::bemap () { return mBeMap; } void ApvlvCmd::canmap (bool canmap) { mCanMap = canmap; } bool ApvlvCmd::canmap () { return mCanMap; } void ApvlvCmd::hascount (bool hascount) { mHasPreCount = hascount; } bool ApvlvCmd::hascount () { return mHasPreCount; } void ApvlvCmd::precount (gint precount) { mPreCount = precount; mHasPreCount = true; } gint ApvlvCmd::precount () { return mPreCount; } void ApvlvCmd::origin (ApvlvCmd * ori) { mOrigin = ori; } ApvlvCmd *ApvlvCmd::origin () { return mOrigin; } const char *ApvlvCmd::c_str () { return mStrCommand.c_str (); } ApvlvCmdKeyv *ApvlvCmd::keyvalv_p () { return &mKeyVals; } ApvlvCmdKeyv ApvlvCmd::keyvalv () { return mKeyVals; } void ApvlvCmd::next (ApvlvCmd * cmd) { mNext = cmd; } ApvlvCmd *ApvlvCmd::next () { return mNext; } gint ApvlvCmd::keyval (guint id) { return id >= mKeyVals.size ()? -1 : mKeyVals[id]; } bool ApvlvCmds::buildmap (const char *os, const char *ms) { ApvlvCmd fir; fir.push (os); ApvlvCmd *secp = new ApvlvCmd; secp->push (ms); ApvlvCmdMap::iterator it; for (it = mMaps.begin (); it != mMaps.end (); ++it) { if (it->first == fir.keyvalv ()) { break; } } if (it != mMaps.end ()) { delete it->second; it->second = secp; } else { mMaps[fir.keyvalv ()] = secp; } return true; } ApvlvCmds::ApvlvCmds () { mTimeoutTimer = -1; mState = CMD_OK; mCmdHead = NULL; if (SK.empty ()) { SK[""] = GDK_BackSpace; SK[""] = GDK_Tab; SK[""] = GDK_Return; SK[""] = GDK_Escape; SK[""] = GDK_space; SK[""] = GDK_less; SK[""] = GDK_backslash; SK[""] = GDK_bar; SK[""] = GDK_Delete; SK[""] = GDK_Up; SK[""] = GDK_Down; SK[""] = GDK_Left; SK[""] = GDK_Right; SK[""] = GDK_Help; SK[""] = GDK_Insert; SK[""] = GDK_Home; SK[""] = GDK_End; SK[""] = GDK_Page_Up; SK[""] = GDK_Page_Down; SK[""] = GDK_KP_Up; SK[""] = GDK_KP_Down; SK[""] = GDK_KP_Left; SK[""] = GDK_KP_Right; SK[""] = GDK_KP_Prior; SK[""] = GDK_KP_Next; SK[""] = GDK_KP_Home; SK[""] = GDK_KP_End; } } ApvlvCmds::~ApvlvCmds () { if (mTimeoutTimer > 0) { g_source_remove (mTimeoutTimer); mTimeoutTimer = -1; } } void ApvlvCmds::append (GdkEventKey * gev) { if (mTimeoutTimer > 0) { g_source_remove (mTimeoutTimer); mTimeoutTimer = -1; } if (mState == GETTING_CMD) { asst (mCmdHead); ApvlvCmdKeyv v = mCmdHead->keyvalv (); v.push_back (gek2guint (gev)); returnType r = ismap (&v); if (r == NO_MATCH) { process (mCmdHead); delete mCmdHead; mCmdHead = NULL; mState = CMD_OK; } } if (mCmdHead == NULL) mCmdHead = new ApvlvCmd; if (mState == CMD_OK) { if (isdigit (gev->keyval) && gev->keyval != '0') { char s[2] = { 0 }; s[0] = gev->keyval; mCountString += s; mState = GETTING_COUNT; mTimeoutTimer = g_timeout_add (3000, apvlv_cmds_timeout_cb, this); return; } } else if (mState == GETTING_COUNT) { if (isdigit (gev->keyval)) { char s[2] = { 0 }; s[0] = gev->keyval; mCountString += s; mTimeoutTimer = g_timeout_add (3000, apvlv_cmds_timeout_cb, this); return; } else { if (mCountString.size () > 0) { mCmdHead->precount (atoi (mCountString.c_str ())); mCountString = ""; } } } bool valid = mCmdHead->append (gev); if (!valid) { mTimeoutTimer = g_timeout_add (3000, apvlv_cmds_timeout_cb, this); return; } mState = GETTING_CMD; returnType ret = ismap (mCmdHead->keyvalv_p ()); if (ret == NEED_MORE) { mTimeoutTimer = g_timeout_add (3000, apvlv_cmds_timeout_cb, this); return; } ApvlvCmd *pcmd = NULL; if (ret == MATCH) { ApvlvCmd *pcmd = getmap (mCmdHead); pcmd->origin (mCmdHead); process (pcmd); pcmd->origin (NULL); pcmd = NULL; } else if (ret == NO_MATCH) { pcmd = process (mCmdHead); } else { asst (0); } delete mCmdHead; mCmdHead = pcmd; mState = CMD_OK; } ApvlvCmd *ApvlvCmds::process (ApvlvCmd * cmd) { guint times = 1; ApvlvCmd *orig = cmd->origin (); if (orig != NULL) { times = orig->precount (); } for (guint i = 0; i < times; ++i) { cmd->process (); } return orig; } returnType ApvlvCmds::ismap (ApvlvCmdKeyv * cvp) { ApvlvCmdMap::iterator it; for (it = mMaps.begin (); it != mMaps.end (); ++it) { if (*cvp == it->first) { return MATCH; } else { guint i; for (i = 0; i < cvp->size (); ++i) { if ((*cvp)[i] != it->first[i]) break; } if (i == cvp->size ()) { return NEED_MORE; } } } return NO_MATCH; } ApvlvCmd *ApvlvCmds::getmap (const char *os) { ApvlvCmd cmd; cmd.push (os); return getmap (&cmd); } ApvlvCmd *ApvlvCmds::getmap (ApvlvCmd * cmd) { ApvlvCmdMap::iterator it; it = mMaps.find (*cmd->keyvalv_p ()); return it != mMaps.end ()? it->second : NULL; } gboolean ApvlvCmds::apvlv_cmds_timeout_cb (gpointer data) { ApvlvCmds *cmds = (ApvlvCmds *) data; if (cmds->mCmdHead != NULL) { cmds->process (cmds->mCmdHead); delete cmds->mCmdHead; cmds->mCmdHead = NULL; } cmds->mState = CMD_OK; return FALSE; } } apvlv-0.1.1-Source/src/ApvlvWindow.cpp100644 1750 1750 33016 11521211167 16751 0ustar00pengdapengda/* * This file is part of the apvlv package * * Copyright (C) 2008 Alf. * * Contact: Alf * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2.0 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * */ /* @CPPFILE ApvlvWindow.cpp * * Author: Alf */ /* @date Created: 2008/09/30 00:00:00 Alf */ #include "ApvlvView.hpp" #include "ApvlvUtil.hpp" #include "ApvlvParams.hpp" #include "ApvlvDir.hpp" #include "ApvlvWindow.hpp" #include namespace apvlv { ApvlvWindow *ApvlvWindow::m_curWindow = NULL; ApvlvWindow::ApvlvWindow (ApvlvCore * doc) { mIsClose = false; type = AW_CORE; if (doc == NULL) { mCore = new ApvlvDoc (0, 0, gParams->values ("zoom")); } else { mCore = doc; } m_son = m_daughter = m_parent = NULL; } ApvlvWindow::~ApvlvWindow () { if (mIsClose) { return; } debug ("delete window: %p", this); mIsClose = true; if (m_parent != NULL) { if (m_parent->m_son == this) { m_parent->m_son = NULL; } else if (m_parent->m_daughter == this) { m_parent->m_daughter = NULL; } } if (type == AW_CORE) { mCore->inuse (false); } else if (type == AW_SP || type == AW_VSP) { if (m_son != NULL) { ApvlvWindow *win = m_son; m_son = NULL; delete win; } if (m_daughter != NULL) { ApvlvWindow *win = m_daughter; m_daughter = NULL; delete win; } g_object_unref (mPaned); } } GtkWidget *ApvlvWindow::widget () { if (type == AW_CORE) { return mCore->widget (); } else if (type == AW_SP || type == AW_VSP) { return mPaned; } else { debug ("type error: %d", type); return NULL; } } void ApvlvWindow::setcurrentWindow (ApvlvWindow * pre, ApvlvWindow * win) { if (pre != NULL && pre->type == AW_CORE) { pre->mCore->setactive (false); } if (win->type == AW_CORE) { win->mCore->setactive (true); } m_curWindow = win; } void ApvlvWindow::delcurrentWindow () { asst (currentWindow ()->istop () == false); ApvlvWindow *crwin = currentWindow (); ApvlvWindow *pwin = crwin->m_parent; ApvlvWindow *child = crwin == pwin->m_son ? pwin->m_daughter : pwin->m_son; ApvlvWindow *cwin = pwin->unbirth (crwin, child); setcurrentWindow (NULL, cwin); } ApvlvWindow *ApvlvWindow::currentWindow () { return m_curWindow; } returnType ApvlvWindow::process (int ct, guint key) { ApvlvWindow *nwin; debug ("input [%d]", key); switch (key) { case CTRL ('w'): case 'k': case 'j': case 'h': case 'l': nwin = getneighbor (ct, key); if (nwin != NULL) { setcurrentWindow (this, nwin); } break; case '-': smaller (ct); break; case '+': bigger (ct); break; default: break; } return MATCH; } ApvlvWindow *ApvlvWindow::getneighbor (int ct, guint key) { switch (key) { case CTRL ('w'): return getnext (ct); case 'k': return getkj (1, false); case 'j': return getkj (1, true); case 'h': return gethl (1, false); case 'l': return gethl (1, true); default: break; } return NULL; } inline ApvlvWindow *ApvlvWindow::getkj (int num, bool down) { ApvlvWindow *cw, *w, *nw, *fw; bool right = false; asst (this && type == AW_CORE); for (cw = fw = NULL, w = this; w != NULL; cw = w, w = w->m_parent) { if (w->type == AW_SP) { if ((cw == w->m_daughter && down == true) || (cw == w->m_son && down == false)) { continue; } else { fw = down ? w->m_daughter : w->m_son; break; } } else if (w->type == AW_VSP) { if (cw != NULL && cw == w->m_daughter) { right = true; } else { right = false; } } } for (nw = w = fw; w != NULL;) { if (w->type == AW_CORE) { nw = w; break; } else if (w->type == AW_SP) { w = down ? w->m_son : w->m_daughter; } else if (w->type == AW_VSP) { w = right ? w->m_daughter : w->m_son; } else { debug ("error type: %d", w->type); return NULL; } } return nw; } inline ApvlvWindow *ApvlvWindow::gethl (int num, bool right) { ApvlvWindow *cw, *w, *nw, *fw; bool down = false; asst (this && type == AW_CORE); for (cw = fw = NULL, w = this; w != NULL; cw = w, w = w->m_parent) { if (w->type == AW_VSP) { if ((cw == w->m_daughter && right == true) || (cw == w->m_son && right == false)) { continue; } else { fw = right ? w->m_daughter : w->m_son; break; } } else if (w->type == AW_SP) { if (cw != NULL && cw == w->m_daughter) { down = true; } else { down = false; } } } for (nw = w = fw; w != NULL;) { if (w->type == AW_CORE) { nw = w; break; } else if (w->type == AW_VSP) { w = right ? w->m_son : w->m_daughter; } else if (w->type == AW_SP) { w = down ? w->m_daughter : w->m_son; } else { debug ("error type: %d", w->type); return NULL; } } return nw; } ApvlvWindow *ApvlvWindow::getnext (int num) { ApvlvWindow *n = getkj (num, true); if (n == NULL) { n = gethl (num, true); if (n == NULL) { n = gethl (num, false); if (n == NULL) n = getkj (num, false); } } return n; } // birth a new AW_CORE window, and the new window beyond the input doc // this made a AW_CORE window to AW_SP|AW_VSP ApvlvWindow *ApvlvWindow::birth (bool vsp, ApvlvCore * doc) { asst (type == AW_CORE); if (doc == mCore) { debug ("can't birth with orign doc, copy it"); doc = NULL; } if (doc == NULL) { doc = mCore->copy (); gView->regloaded (doc); } if (doc == NULL) { gView->errormessage ("can't split"); return this; } ApvlvWindow *nwindow = new ApvlvWindow (doc); nwindow->m_parent = this; m_son = nwindow; ApvlvWindow *nwindow2 = new ApvlvWindow (mCore); nwindow2->m_parent = this; m_daughter = nwindow2; mPaned = vsp == false ? gtk_vpaned_new () : gtk_hpaned_new (); g_object_ref (mPaned); g_signal_connect (G_OBJECT (mPaned), "button-release-event", G_CALLBACK (apvlv_window_paned_resized_cb), this); if (m_parent) { void (*panedcb) (GtkPaned *, GtkWidget *); GtkWidget *parent = m_parent->mPaned; if (gtk_paned_get_child1 (GTK_PANED (parent)) == widget ()) { panedcb = gtk_paned_add1; } else { panedcb = gtk_paned_add2; } gtk_container_remove (GTK_CONTAINER (parent), widget ()); panedcb (GTK_PANED (parent), mPaned); } else { replace_widget (widget (), mPaned); } gtk_paned_pack1 (GTK_PANED (mPaned), nwindow->widget (), TRUE, TRUE); gtk_paned_pack2 (GTK_PANED (mPaned), nwindow2->widget (), TRUE, TRUE); type = vsp == false ? AW_SP : AW_VSP; if (type == AW_SP) { nwindow->setsize (mWidth, mHeight / 2); nwindow2->setsize (mWidth, mHeight / 2); } else if (type == AW_VSP) { nwindow->setsize (mWidth / 2, mHeight); nwindow2->setsize (mWidth / 2, mHeight); } gtk_widget_show_all (mPaned); setcurrentWindow (nwindow2, nwindow); return nwindow; } // unbirth a child // @param 1, be delete // @param 2, be unbirth, that is up to the parent // return the new child ApvlvWindow *ApvlvWindow::unbirth (ApvlvWindow * dead, ApvlvWindow * child) { asst (type == AW_SP || type == AW_VSP); if (m_parent) { void (*panedcb) (GtkPaned *, GtkWidget *); GtkWidget *parent = m_parent->mPaned; if (gtk_paned_get_child1 (GTK_PANED (parent)) == mPaned) { panedcb = gtk_paned_add1; } else { panedcb = gtk_paned_add2; } gtk_container_remove (GTK_CONTAINER (mPaned), child->widget ()); gtk_container_remove (GTK_CONTAINER (parent), mPaned); panedcb (GTK_PANED (parent), child->widget ()); } else { gtk_container_remove (GTK_CONTAINER (mPaned), child->widget ()); replace_widget (mPaned, child->widget ()); } if (child->type == AW_CORE) { ApvlvCore *doc = child->getCore (); type = AW_CORE; mCore = doc; } else if (child->type == AW_SP || child->type == AW_VSP) { type = child->type; mPaned = child->mPaned; m_son = child->m_son; m_son->m_parent = this; m_daughter = child->m_daughter; m_daughter->m_parent = this; child->type = AW_NONE; } gtk_widget_show_all (widget ()); if (dead != NULL) delete dead; if (child != NULL) delete child; ApvlvWindow *win; for (win = this; win->type != AW_CORE; win = win->m_son); return win; } bool ApvlvWindow::istop () { return m_parent == NULL ? true : false; } void ApvlvWindow::getsize (int *width, int *height) { if (width) { *width = mWidth; } if (height) { *height = mHeight; } } void ApvlvWindow::setsize (int width, int height) { mWidth = width - 2; mHeight = height - 2; // debug ("mWidth: %d, mHeight: %d", mWidth, mHeight); if (type == AW_CORE) { mCore->setsize (mWidth, mHeight); } else if (type == AW_SP || type == AW_VSP) { g_timeout_add (50, apvlv_window_resize_children_cb, this); } } void ApvlvWindow::setCore (ApvlvCore * doc) { debug ("widget (): %p, doc->widget (): %p", widget (), doc->widget ()); if (type == AW_CORE) { mCore->inuse (false); } replace_widget (widget (), doc->widget ()); doc->inuse (true); type = AW_CORE; mCore = doc; } ApvlvCore *ApvlvWindow::getCore () { asst (type == AW_CORE); ApvlvCore *rdoc = mCore; return rdoc; } void ApvlvWindow::smaller (int times) { if (m_parent == NULL) return; int val = gtk_paned_get_position (GTK_PANED (m_parent->mPaned)); int len = 20 * times; m_parent->m_son == this ? val -= len : val += len; gtk_paned_set_position (GTK_PANED (m_parent->mPaned), val); m_parent->resize_children (); } void ApvlvWindow::bigger (int times) { if (m_parent == NULL) return; int val = gtk_paned_get_position (GTK_PANED (m_parent->mPaned)); int len = 20 * times; m_parent->m_son == this ? val += len : val -= len; gtk_paned_set_position (GTK_PANED (m_parent->mPaned), val); m_parent->resize_children (); } gboolean ApvlvWindow::apvlv_window_paned_resized_cb (GtkWidget * wid, GdkEventButton * but, ApvlvWindow * win) { win->resize_children (); return FALSE; } gboolean ApvlvWindow::resize_children () { int mw1 = mWidth, mw2 = mWidth, mh1 = mHeight, mh2 = mHeight; int mi = GTK_PANED (mPaned)->min_position; int ma = GTK_PANED (mPaned)->max_position; int mv = gtk_paned_get_position (GTK_PANED (mPaned)); int ms = ma - mi; if (ms != 0) { if (type == AW_SP) { mh1 = (mHeight * (mv - mi)) / ms - 1; mh2 = mHeight - mh1 - 1; } else if (type == AW_VSP) { mw1 = (mWidth * (mv - mi)) / ms - 1; mw2 = mWidth - mw1 - 1; } m_son->setsize (mw1, mh1); m_daughter->setsize (mw2, mh2); return TRUE; } else { return FALSE; } } gboolean ApvlvWindow::apvlv_window_resize_children_cb (gpointer data) { ApvlvWindow *win = (ApvlvWindow *) data; return win->resize_children () == TRUE ? FALSE : FALSE; } } apvlv-0.1.1-Source/src/CMakeLists.txt100644 1750 1750 5626 11521211167 16513 0ustar00pengdapengdaIF (WIN32) ADD_DEFINITIONS (-D_CRT_SECURE_NO_WARNINGS) ELSE (WIN32) SET (CMAKE_CXX_FLAGS "-Wall -fno-strict-aliasing") OPTION (APVLV_ENABLE_DEBUG "If build binary with debug infomations." OFF) IF (APVLV_ENABLE_DEBUG) SET (CMAKE_CXX_FLAGS "-D_DEBUG -g ${CMAKE_CXX_FLAGS}") ELSE (APVLV_ENABLE_DEBUG) SET (CMAKE_CXX_FLAGS "-O2 ${CMAKE_CXX_FLAGS}") ENDIF (APVLV_ENABLE_DEBUG) ENDIF (WIN32) SET (HEADERS ApvlvCmds.hpp ApvlvCore.hpp ApvlvDir.hpp ApvlvDoc.hpp ApvlvFile.hpp ApvlvInfo.hpp ApvlvMenu.hpp ApvlvParams.hpp ApvlvUtil.hpp ApvlvView.hpp ApvlvWindow.hpp ) SET (SOURCES ApvlvCmds.cpp ApvlvCore.cpp ApvlvDir.cpp ApvlvDoc.cpp ApvlvFile.cpp ApvlvInfo.cpp ApvlvMenu.cpp ApvlvParams.cpp ApvlvUtil.cpp ApvlvView.cpp ApvlvWindow.cpp main.cpp ) ADD_EXECUTABLE (apvlv ${HEADERS} ${SOURCES}) TARGET_LINK_LIBRARIES (apvlv ${GTK2_LIBRARIES} ${GLIB2_LIBRARIES} ${GTHREAD2_LIBRARIES} ${APVLV_REQ_LIBRARIES}) IF (WIN32) ADD_DEPENDENCIES (apvlv poppler) IF (APVLV_WITH_UMD) ADD_DEPENDENCIES (apvlv umd) ENDIF (APVLV_WITH_UMD) ENDIF (WIN32) IF (WIN32) INSTALL (TARGETS apvlv DESTINATION .) FIND_FILE (LIBATK libatk-1.0-0.dll) FIND_FILE (LIBGIO libgio-2.0-0.dll) FIND_FILE (LIBCAIRO libcairo-2.dll) FIND_FILE (LIBPANGOCAIRO libpangocairo-1.0-0.dll) FIND_FILE (LIBPANGOFT2 libpangoft2-1.0-0.dll) FIND_FILE (LIBGDKPIXBUF libgdk_pixbuf-2.0-0.dll) FIND_FILE (LIBGDK libgdk-win32-2.0-0.dll) FIND_FILE (LIBGLIB libglib-2.0-0.dll) FIND_FILE (LIBGMODULE libgmodule-2.0-0.dll) FIND_FILE (LIBPANGO libpango-1.0-0.dll) FIND_FILE (LIBGTHREAD libgthread-2.0-0.dll) FIND_FILE (LIBPNG libpng14-14.dll) FIND_FILE (LIBGTK libgtk-win32-2.0-0.dll) FIND_FILE (LIBGOBJECT libgobject-2.0-0.dll) FIND_FILE (LIBPANGOWIN32 libpangowin32-1.0-0.dll) FIND_FILE (LIBZLIB1 zlib1.dll) FIND_FILE (FREETYPE6 freetype6.dll) INSTALL (FILES ${LIBATK} ${LIBGIO} ${LIBCAIRO} ${LIBPANGOCAIRO} ${LIBGDKPIXBUF} ${LIBGDK} ${LIBGLIB} ${LIBGMODULE} ${LIBPANGO} ${LIBGTHREAD} ${LIBPNG} ${LIBGTK} ${LIBGOBJECT} ${LIBPANGOFT2} ${LIBPANGOWIN32} ${LIBZLIB1} ${FREETYPE6} ${DJVULIBRE_DIR}/libdjvulibre.dll ${DJVULIBRE_DIR}/libjpeg.dll DESTINATION .) ELSE (WIN32) INSTALL (TARGETS apvlv DESTINATION bin) ENDIF (WIN32) apvlv-0.1.1-Source/src/ApvlvFile.hpp100644 1750 1750 13060 11521211167 16363 0ustar00pengdapengda/* * This file is part of the apvlv package * Copyright (C) <2008> * * Contact: Alf * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * */ /* @CFILE ApvlvFile.hpp xxxxxxxxxxxxxxxxxxxxxxxxxx. * * Author: Alf */ /* @date Created: 2009/11/20 19:37:44 Alf*/ #ifndef _APVLV_FILE_H_ #define _APVLV_FILE_H_ #ifdef HAVE_CONFIG_H # include "config.hpp" #endif #include #include #ifdef HAVE_LIBDJVU # include #endif #ifdef HAVE_LIBUMD #define LIBUMD_ENABLE_GTK # include #endif #include #include using namespace std; namespace apvlv { // // link to a url, or a page num // struct ApvlvLink { string mUrl; int mPage; }; typedef vector < ApvlvLink > ApvlvLinks; // // position of a search result, or just a area // struct ApvlvPos { double x1, x2, y1, y2; }; typedef vector < ApvlvPos > ApvlvPoses; struct ApvlvFileIndex { string title; int page; vector < ApvlvFileIndex > children; }; typedef vector < ApvlvFileIndex >::iterator ApvlvFileIndexIter; class ApvlvFile { public: ApvlvFile (const char *filename, bool check); virtual ~ ApvlvFile (); static ApvlvFile *newfile (const char *filename, bool check = false); virtual bool writefile (const char *filename) = 0; virtual bool pagesize (int page, int rot, double *x, double *y) = 0; virtual int pagesum () = 0; virtual bool pagetext (int, int, int, int, int, char **) = 0; virtual bool render (int, int, int, double, int, GdkPixbuf *, char *buffer = NULL) = 0; virtual ApvlvPoses *pagesearch (int pn, const char *str, bool reverse = false) = 0; virtual bool pageselectsearch (int, int, int, double, int, GdkPixbuf *, char *, int, ApvlvPoses *) = 0; virtual ApvlvLinks *getlinks (int pn) = 0; virtual ApvlvFileIndex *new_index () = 0; virtual void free_index (ApvlvFileIndex *) = 0; virtual bool pageprint (int pn, cairo_t * cr) = 0; protected: ApvlvFileIndex * mIndex; unsigned short mIndexRef; gchar *mRawdata; guint mRawdataSize; }; class ApvlvPDF:public ApvlvFile { public: ApvlvPDF (const char *filename, bool check = true); ~ApvlvPDF (); bool writefile (const char *filename); bool pagesize (int page, int rot, double *x, double *y); int pagesum (); bool pagetext (int, int, int, int, int, char **); bool render (int, int, int, double, int, GdkPixbuf *, char *); bool pageselectsearch (int, int, int, double, int, GdkPixbuf *, char *, int, ApvlvPoses *); ApvlvPoses *pagesearch (int pn, const char *s, bool reverse = false); ApvlvLinks *getlinks (int pn); ApvlvFileIndex *new_index (); void free_index (ApvlvFileIndex *); bool pageprint (int pn, cairo_t * cr); private: bool walk_poppler_index_iter (ApvlvFileIndex * titr, PopplerIndexIter * iter); PopplerDocument *mDoc; }; class ApvlvDJVU:public ApvlvFile { public: ApvlvDJVU (const char *filename, bool check = true); ~ApvlvDJVU (); bool writefile (const char *filename); bool pagesize (int page, int rot, double *x, double *y); int pagesum (); bool pagetext (int, int, int, int, int, char **); bool render (int, int, int, double, int, GdkPixbuf *, char *); bool pageselectsearch (int, int, int, double, int, GdkPixbuf *, char *, int, ApvlvPoses *); ApvlvPoses *pagesearch (int pn, const char *s, bool reverse = false); ApvlvLinks *getlinks (int pn); ApvlvFileIndex *new_index (); void free_index (ApvlvFileIndex *); bool pageprint (int pn, cairo_t * cr); private: #ifdef HAVE_LIBDJVU ddjvu_context_t * mContext; ddjvu_document_t *mDoc; #endif }; class ApvlvUMD:public ApvlvFile { public: ApvlvUMD (const char *filename, bool check = true); ~ApvlvUMD (); bool writefile (const char *filename); bool pagesize (int page, int rot, double *x, double *y); int pagesum (); bool pagetext (int, int, int, int, int, char **); bool render (int, int, int, double, int, GdkPixbuf *, char *); bool pageselectsearch (int, int, int, double, int, GdkPixbuf *, char *, int, ApvlvPoses *); ApvlvPoses *pagesearch (int pn, const char *s, bool reverse = false); ApvlvLinks *getlinks (int pn); ApvlvFileIndex *new_index (); void free_index (ApvlvFileIndex *); bool pageprint (int pn, cairo_t * cr); private: #ifdef HAVE_LIBUMD umd_t *mUmd; #endif }; }; #endif apvlv-0.1.1-Source/README100644 1750 1750 1130 11521211167 14026 0ustar00pengdapengda Apvlv ======== Apvlv is a PDF viewer which behaves like Vim. For more general information about Apvlv please visit the project's website at http://apvlv.googlecode.com This software is licensed under the GNU General Public License (GPL). The icons used by this software are part of the Gnome Icon Theme, which is copyright The GNOME Project and released under the GNU General Public License (GPL). Requirements ============ GTK+ version 2.6.0 or higher ( http://www.gtk.org/ ) Poppler version 0.5.0 with glib bindings ( http://poppler.freedesktop.org/ ) apvlv-0.1.1-Source/Startup.pdf100644 1750 1750 241571 11521211167 15362 0ustar00pengdapengda%PDF-1.4 % 5 0 obj << /S /GoTo /D [6 0 R /FitH ] >> endobj 10 0 obj << /Length 811 /Filter /FlateDecode >> stream xڽUN0}߯[Rc<ƨJ/ !TvC`Kd$٥}qH[$3g<, #Gd j-HC-. Ifsr\G|;Q^b+aX|܍7pU؟d?ڭ~-c 1RsXj!.ŔG fLPX0x0ʭCFT̒ >:|9 *ͮg,4eY}sA_AJ*@@mrNܟ5MBq3?~{YHxv}0 m`)`E&i4wi dqAph(v 7|b }GG;UYutϟ$r׹Ƥ]]5zo/eY.swYD*A,2o l(mp2pjݘuX^|}نhGK/)p<3[ф* endstream endobj 6 0 obj << /Type /Page /Contents 10 0 R /Resources 9 0 R /MediaBox [0 0 595.276 841.89] /Parent 21 0 R /Annots [ 7 0 R 8 0 R ] >> endobj 7 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [248.468 587.554 390.725 607.479] /Subtype/Link/A<> >> endobj 8 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [240.642 218.392 397.27 230.384] /Subtype/Link/A<> >> endobj 11 0 obj << /D [6 0 R /XYZ 90 722.796 null] >> endobj 12 0 obj << /D [6 0 R /XYZ 90 697.89 null] >> endobj 9 0 obj << /Font << /F17 13 0 R /F16 14 0 R /F18 15 0 R /F20 16 0 R /F21 17 0 R /F22 18 0 R /F23 19 0 R /F24 20 0 R >> /ProcSet [ /PDF /Text ] >> endobj 24 0 obj << /Length 1568 /Filter /FlateDecode >> stream xڽWY6~ϯp,kh6hlMd0tPZ{ͦ/}p8$0_| _<}%HF/w/԰LvW$Vk!+%mVknwM-\ B3cZI&4~)oHLb*a\+b[e$5-fh ;һ~{/o(OpOڼag;';Zk7=qƧ]x3nERt >ʔ"u$X2zAȘ,|@eQ%{՜#,袇=3ǣX^wSx5-vK?^zOd$#8ȅ.->c0?j8JxZ9mbtlO&ѹXc܀Ga ^u+R@>&Ԡ/NĘC7Ȳĩ1/kZ`hD UT-^3'sPoO<\Z@ U*,:ZTi}?`6NvDU%ѧ--%_cFf+Yaru&>*y&fF"" 6/R=>84PH(REa'+Q> endobj 25 0 obj << /D [23 0 R /XYZ 90 722.796 null] >> endobj 26 0 obj << /D [23 0 R /XYZ 90 697.89 null] >> endobj 22 0 obj << /Font << /F26 27 0 R /F21 17 0 R /F16 14 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 30 0 obj << /Length 1190 /Filter /FlateDecode >> stream xڅVmoF _ad,^%ݰȆ-i+}زEIN?(V,_#CbWzu"aRXm/0bY0B:뺼܅JLsMmVfJE$?Dmv(\W%)В؀~(z9q. L7bbfmIoqacWu*Mnْ1/6l.;"c玴H̲^ګN'CC\ pOMG?Sg02r]"(xuȦUj"xp/nJ9i.|jBi$%A5t1]HލЉ",M!EǶ,%Q,je޵H*Sn!* ! vUGi ~UC!k[ˈ({< 7+ c֠ޫ@zYWu]dM+"SmcyMި$ft8$ntC!;Grx4D5$qa;ibK w3;u`*panZB%L[=x ٷ'(v[CMVZP* fS9KM:B *"44;QT76?~;fI}2P9-LӞjOLJiX1Cӡw &Ϸmʘ Z= w2*Pmkx8f5ə_W,7 endstream endobj 29 0 obj << /Type /Page /Contents 30 0 R /Resources 28 0 R /MediaBox [0 0 595.276 841.89] /Parent 21 0 R >> endobj 31 0 obj << /D [29 0 R /XYZ 90 722.796 null] >> endobj 32 0 obj << /D [29 0 R /XYZ 90 697.89 null] >> endobj 33 0 obj << /D [29 0 R /XYZ 90 668.38 null] >> endobj 35 0 obj << /D [29 0 R /XYZ 90 439.947 null] >> endobj 28 0 obj << /Font << /F26 27 0 R /F28 34 0 R /F21 17 0 R /F16 14 0 R /F20 16 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 38 0 obj << /Length 885 /Filter /FlateDecode >> stream xڽVߋ8~߿2ZK-+%{p}Pb%6Zr3gvӃ{4q M$u-ïO Jqw!ADR<L[ٖO *WH $1XcL*;0nOVtAaf1{5Ђpm9bT`B꾪[ rв1bzO[E\E#.EEfKN"xN!Pwzl'[`aTHjcqlmfK{̻)Ua. # ɾRངmCcѢz[L_lnIܦ5<-vU=i.w&-h$T_76ڴX9fk*ӅJlLI䠋IR |tm+\oz{lɼ6+{bXSzƹGS3{Ŋ_bC-liǛsj"dȎV"X\:YEH~̯çE1$nw]&?2>G"|Ɔ=w$l;8NҧF$ituS0"8EoE}2~X wyzxVȟ@*S8XCn7_JCz O~oem  /sR)> endobj 39 0 obj << /D [37 0 R /XYZ 90 722.796 null] >> endobj 40 0 obj << /D [37 0 R /XYZ 90 697.89 null] >> endobj 36 0 obj << /Font << /F26 27 0 R /F16 14 0 R /F21 17 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 43 0 obj << /Length 589 /Filter /FlateDecode >> stream xVn@+XTnHvZʕm$O8}s*I-?S7ݏax~fՂß8a% $&/2 endstream endobj 42 0 obj << /Type /Page /Contents 43 0 R /Resources 41 0 R /MediaBox [0 0 595.276 841.89] /Parent 21 0 R >> endobj 44 0 obj << /D [42 0 R /XYZ 90 722.796 null] >> endobj 41 0 obj << /Font << /F18 15 0 R /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 47 0 obj << /Length 720 /Filter /FlateDecode >> stream xVK0WD\J$Nl' VB6ncm<,;cM7vAp;73ߌzk/n'zQbo2R{4%(7Ͻ/9:%Q%J|U΂S_VȨ> 1CiFU]{cxwV/(iAy[\F !Lﻐn-EZhatMY@y}obԂ FRU UZ/E0-N M#58,NklEgQ܊мΘ/(iɧpISs*̩QMZTFpLm>9#x4v÷h Q"PvM϶Va]I^NV\V䠱Ǥ8t}LiK$, 83]84Ɯ3#̰/z6DiFAwH,'&+i9T-ܰ6,ke<gyϐä._]flƂ뽜ژn(DIrNPưSz3 Ne(u-IH{(ڍ894 ߶_%1{Q8a7),niC-ֳrKkXaFVv\? N>%Y@cenu4tTJ|udw{yQ+X&) d m_Wa;B!$vA:0y7rK endstream endobj 46 0 obj << /Type /Page /Contents 47 0 R /Resources 45 0 R /MediaBox [0 0 595.276 841.89] /Parent 21 0 R >> endobj 48 0 obj << /D [46 0 R /XYZ 90 722.796 null] >> endobj 45 0 obj << /Font << /F16 14 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 51 0 obj << /Length 706 /Filter /FlateDecode >> stream xVo0~_ŋŶcHHxx6MnR{9kGCR}eo; EʂlIA%1\,e 0 1,4}x1AbC<B f$FȈMTx~(, Əޡp[j .oo'2&}tqżC>w[{}?}'M~^G1 Pڢ}2xpY a b}WFHT8m˼83j6iэ jq8$SH Oא7]Mͦ1Uprtc `+:]Eni^=ܐS'tv~r#4^5:uu,tc'~p2 ϢX*2Jd<;&h-wǵVӼGaj}YW~C/͍ dŅ[.ʊ#%DE)h#I7/O endstream endobj 50 0 obj << /Type /Page /Contents 51 0 R /Resources 49 0 R /MediaBox [0 0 595.276 841.89] /Parent 53 0 R >> endobj 52 0 obj << /D [50 0 R /XYZ 90 722.796 null] >> endobj 49 0 obj << /Font << /F18 15 0 R /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 56 0 obj << /Length 1112 /Filter /FlateDecode >> stream xڭWK4ϯmivH 분!tݑ2q ]k& N.W쪯^N$.w?0PIxp8y<͂C| ySʲ9G~PNR.UI8erT}QX*I cF1>d!eBU%cQ׺ԋ6 LZ1:`,%B f9cuK aKt˽2:)IE:}#+T蛯W{2xαh+FЃ[kY]Ūw0f\H%R7DMY\- 9{DW5­6@-=v\?Km[WbLjOl' ]FثqM1E閚8-a[]pd]P[ŦD[+R랄{>|u/7}-( Aa+Ò go6űR|b[8OqJb*|ɡcIt$OYhl[D(*M:oy ~ i: Cmw_zZ_1+ghC}MW]Z\ ,zx CI9KÃ'F.۩6Vz@盪/tq00uv:_(lwSetY[fs̉R>)F?[@k endstream endobj 55 0 obj << /Type /Page /Contents 56 0 R /Resources 54 0 R /MediaBox [0 0 595.276 841.89] /Parent 53 0 R >> endobj 57 0 obj << /D [55 0 R /XYZ 90 722.796 null] >> endobj 58 0 obj << /D [55 0 R /XYZ 90 697.89 null] >> endobj 59 0 obj << /D [55 0 R /XYZ 90 346.844 null] >> endobj 60 0 obj << /D [55 0 R /XYZ 90 305.435 null] >> endobj 61 0 obj << /D [55 0 R /XYZ 90 264.026 null] >> endobj 62 0 obj << /D [55 0 R /XYZ 90 224.465 null] >> endobj 54 0 obj << /Font << /F26 27 0 R /F21 17 0 R /F16 14 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 65 0 obj << /Length 830 /Filter /FlateDecode >> stream xڵVM0 Gںv"QHJ%+n6M*NZ{ҴRyx8λ}Ǐh%\;YL8t4Y;y l܀OJz٫/u B3 ʲ+ѹ0HFtQ5\J=Etf> endobj 66 0 obj << /D [64 0 R /XYZ 90 722.796 null] >> endobj 67 0 obj << /D [64 0 R /XYZ 90 342.661 null] >> endobj 68 0 obj << /D [64 0 R /XYZ 90 299.679 null] >> endobj 69 0 obj << /D [64 0 R /XYZ 90 256.698 null] >> endobj 70 0 obj << /D [64 0 R /XYZ 90 213.716 null] >> endobj 71 0 obj << /D [64 0 R /XYZ 90 170.734 null] >> endobj 72 0 obj << /D [64 0 R /XYZ 90 112.61 null] >> endobj 63 0 obj << /Font << /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 75 0 obj << /Length 150 /Filter /FlateDecode >> stream x]! w# T(P`5Q3[/{&} `"<q8[y&(XJH8.@aս~ ڛ$Re]u`cLɠ;zvY$o<=i,Z/9frrnzk:T4 endstream endobj 74 0 obj << /Type /Page /Contents 75 0 R /Resources 73 0 R /MediaBox [0 0 595.276 841.89] /Parent 53 0 R >> endobj 76 0 obj << /D [74 0 R /XYZ 90 722.796 null] >> endobj 77 0 obj << /D [74 0 R /XYZ 90 697.89 null] >> endobj 73 0 obj << /Font << /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 80 0 obj << /Length 580 /Filter /FlateDecode >> stream xVMs0WfzL鴗@A6" c{2Œ{!E{EW[GG!cJ  ؄PfnEȍzU9yֻG\x AC1qkyވ:%ٔpx]S&8Y2ɕZo{&czx$JM8ٔNT;Q9)ܲC* QIwEL: ˑ:.eQ& B HлQ -A{ >H SIAM[& ΊćBޞm8Χ> gK)tùf0)Q'`7 ^JȆX6AP^®-yT|}3;bp2EiE ppV,/b,(Nq[Hh r>榚Vځz!hQk"Kdf+(7ڎ~I ۤD^#2M?-͟Ao2GpqO'!c')V;ۣw)"d-ZA4 endstream endobj 79 0 obj << /Type /Page /Contents 80 0 R /Resources 78 0 R /MediaBox [0 0 595.276 841.89] /Parent 53 0 R >> endobj 81 0 obj << /D [79 0 R /XYZ 90 722.796 null] >> endobj 82 0 obj << /D [79 0 R /XYZ 90 697.89 null] >> endobj 78 0 obj << /Font << /F26 27 0 R /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 85 0 obj << /Length 561 /Filter /FlateDecode >> stream xڽU;0+Y̜1OLI4t c#Ċ;sgvJhۧ#X9 xND< |;]Ds}hĿ{6. C7kBԵ=BцR{G<%klZ_!Hl;>ĠOB;rώ ?-L$eǀVRx)9]kҤ/LAJX4&S٤BOp/O(`ar'![tS-,Ϣ`c{p^vŗ yLc-Ś&A'jIs5q 5כ ;nm߈Cc\Q>):7Z }tGB3?/ZM pIE)aHQMjbE?)a^ЄUI \>/.`> endobj 86 0 obj << /D [84 0 R /XYZ 90 722.796 null] >> endobj 83 0 obj << /Font << /F16 14 0 R >> /ProcSet [ /PDF /Text ] >> endobj 92 0 obj << /Length 305 /Filter /FlateDecode >> stream xڥMk@{L~dWJBz,1 46 eޏggQ,9)lFPLZb- c58EIR"xbjyM)HeSAnE9—r\-߶m5$;E1q<:݂A3ƛ=lq87g Js.pӋMhnqJfdg!B]/5d!:_l7#C[l+í-e|;'n:i|=H fP!ް&Ӻgӭ%#$"z*{ endstream endobj 91 0 obj << /Type /Page /Contents 92 0 R /Resources 90 0 R /MediaBox [0 0 595.276 841.89] /Parent 95 0 R /Annots [ 87 0 R 88 0 R 89 0 R ] >> endobj 87 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [153.584 651.803 354.899 671.728] /Subtype/Link/A<> >> endobj 88 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [173.621 633.87 337.729 653.795] /Subtype/Link/A<> >> endobj 89 0 obj << /Type /Annot /Border[0 0 0]/H/I/C[0 1 1] /Rect [133.023 615.937 326.956 635.862] /Subtype/Link/A<> >> endobj 93 0 obj << /D [91 0 R /XYZ 90 722.796 null] >> endobj 94 0 obj << /D [91 0 R /XYZ 90 697.89 null] >> endobj 90 0 obj << /Font << /F26 27 0 R /F16 14 0 R /F20 16 0 R /F18 15 0 R >> /ProcSet [ /PDF /Text ] >> endobj 96 0 obj [733.3 733.3 702.8 794.4 641.7 611.1 733.3 794.4 330.6 519.4 763.9 580.6 977.8 794.4 794.4 702.8 794.4 702.8 611.1 733.3 763.9 733.3 1038.9 733.3 733.3 672.2 343.1 558.3 343.1 550 305.6 305.6 525 561.1 488.9 561.1 511.1 336.1 550 561.1 255.6 286.1 530.6 255.6 866.7 561.1 550 561.1 561.1 372.2 421.7 404.2 561.1 500] endobj 97 0 obj [312.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 562.5 312.5 312.5 342.6 875 531.3 531.3 875 849.5 799.8 812.5 862.3 738.4 707.2 884.3 879.6 419 581 880.8 675.9 1067.1 879.6 844.9 768.5 844.9 839.1 625 782.4 864.6 849.5 1162 849.5 849.5 687.5 312.5 581 312.5 562.5 312.5 312.5 546.9 625 500 625 513.3 343.7 562.5 625 312.5 343.7 593.8 312.5 937.5 625 562.5 625 593.8 459.5 443.8 437.5 625 593.8 812.5 593.8 593.8] endobj 98 0 obj [525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525 525] endobj 99 0 obj [666.7 666.7 638.9 722.2 597.2 569.4 666.7 708.3 277.8 472.2 694.4 541.7 875 708.3 736.1 638.9 736.1 645.8 555.6 680.6 687.5 666.7 944.4 666.7 666.7 611.1 288.9 500 288.9 500 277.8 277.8 480.6 516.7 444.4 516.7 444.4 305.6 500 516.7 238.9 266.7 488.9 238.9 794.4 516.7 500 516.7 516.7 341.7 383.3 361.1 516.7 461.1] endobj 100 0 obj [277.8 388.9 388.9 500 777.8 277.8 333.3 277.8 500 500 500 500 500 500 500 500 500 500 500 277.8 277.8 277.8 777.8 472.2 472.2 777.8 750 708.3 722.2 763.9 680.6 652.8 784.7 750 361.1 513.9 777.8 625 916.7 750 777.8 680.6 777.8 736.1 555.6 722.2 750 750 1027.8 750 750 611.1 277.8 500 277.8 500 277.8 277.8 500 555.6 444.4 555.6 444.4 305.6 500 555.6 277.8 305.6 527.8 277.8 833.3 555.6 500 555.6 527.8 391.7 394.4 388.9 555.6 527.8] endobj 101 0 obj [647 649.9 625.6 704.3 583.3 556.1 652.8 686.3 266.2 459.5 674.2 528.9 849.5 686.3 722.2 622.7 722.2 630.2 544 667.8 666.7 647 919 647 647 598.4 283 489.6 283 489.6 272 272 468.7 502.3 435.2 502.3 435.2 299.2 489.6 502.3 230.3 257.5 475.1 230.3 774.3 502.3 489.6 502.3 502.3 332.8 375.3 353.6 502.3 447.9] endobj 102 0 obj [514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6 514.6] endobj 103 0 obj [761.6 489.6 761.6] endobj 104 0 obj [571.2 544 544 816 816 272 299.2 489.6 489.6 489.6 489.6 489.6 734 435.2 489.6 707.2 761.6 489.6 883.8 992.6 761.6 272 272 489.6 816 489.6 816 761.6 272 380.8 380.8 489.6 761.6 272 326.4 272 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 489.6 272 272 272 761.6 462.4 462.4 761.6 734 693.4 707.2 747.8 666.2 639 768.3 734 353.2 503 761.2 611.8 897.2 734 761.6 666.2 761.6 720.6 544 707.2 734 734 1006 734 734 598.4 272 489.6 272 489.6 272 272 489.6 544 435.2 544 435.2 299.2 489.6 544 272 299.2 516.8 272 816 544 489.6 544 516.8 380.8 386.2 380.8 544 516.8 707.2 516.8 516.8 435.2 489.6 979.2] endobj 105 0 obj [249.6 354.1 354.1 458.6 719.8 249.6 301.9 249.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 458.6 249.6 249.6 249.6 719.8 432.5 432.5 719.8 693.3 654.3 667.6 706.6 628.2 602.1 726.3 693.3 327.6 471.5 719.4 576 850 693.3 719.8 628.2 719.8 680.5 510.9 667.6 693.3 693.3 954.5 693.3 693.3 563.1 249.6 458.6 249.6 458.6 249.6 249.6 458.6 510.9 406.4 510.9 406.4 275.8 458.6 510.9 249.6 275.8 484.7 249.6 772.1 510.9 458.6 510.9 484.7 354.1 359.4 354.1 510.9 484.7 667.6] endobj 106 0 obj << /Length1 1258 /Length2 6238 /Length3 0 /Length 6998 /Filter /FlateDecode >> stream xڭeXݺ.Qa`nbhB$$EBF %PR8}O5^ϳuQG( E.H ,ה3< Byw5``- vH<_IYg=i9k@= ur{<`0jAl`.5C=]{hIZpq@apB^-z,C?+y:9iY;UUf ]=0w& swTcؿN5*"bdd#!vv ?Ak{?e:>3F'g)@P{X[O` yy\HtzIp;_)$_$v^UM^HM?u^$M^?@@?-у~ #8`0(@X!0J  g0%(żR;rMZu]ۉ%q*ƹTkrQMM+QM/~hL^kn2>۽w;SK%IO3v+l-0btywg (v2eg#Is+X&IJ^ro?Dy^缺ĂY]39% (^Ll (&17(#7Hx sRr $H$֬D;vՕ*"B? 1jg(#r՗B4 UlF|lեX9RX|4&Q[@0<Vm\|n!q0R$_Zh$5bNҪ0u/y?gX b6p|6یWC)(ulэ `X>) C3jHbC̏+. @MqAeRZk>6 ?-|!"xm!I9Kj7BO^SAE.)̴&'4w\Cb^k!m}r\DLp5CD?gP %zߚWz@\wi^1;1 @xm C)6"*9hw(]%׍H@o= r80oQC[4S,2 SS]ӯSWݗoZ紎֟tRk@dnayuP7zDa, r.vɋY'ѱ=>Drje6|,?OWb 8L\Km#7S!^~獼yI^ m/taF~RvbABjMGҟMZ6yv)up2s4vV=܌$-!򎏞r\'ClgJcKDǹ 96#>}|Yk#?1V5FiqC3-kPyD/"K@N6oI!w fhdnQ(ĸ?"!cs+p"req;3S ٙNOcȤWrmpj Sb!kL{7?#"8e%~Q 2DP2g.WR6"[69sG) ,)aZbAN~# }R1rXU_kfHXM0hRMU7]zai7Cg67ݘibe,/3sOjl]loԶ,pЯk ~{i}f~Is4H m\ 28< jNh /gkgR:1ZT$HѾn+i/Kcf|!r"t1e8{]&VjtwFǪGfRl|tdE},HcT?سaH޲%!M6w7)Cf^>-p`٧ NdG+% OtlțB(lZkP䇽Cls:-(-x0g@>/X"tnNp%r q ٯ>- _þ}J״]\ %k}H(jqFًIG.Nث){l )qY2 +8q͂s2ř_CpUDŎctYEi$V>iזaʹCcWDu+h?ac1عOxɶQ+Dk E$[%eHetfIHQ/ySo)bɭ9U+4@G> lI͖udf4^.7Nݼt6o@}td00q r"ː"P"*i $& 7-qm\ycՊܙx) gz+>’U>ϱ"t-cvRBf18|X)wUSZ03\Fܔ̅ǙQ}W8O)%9e9允gtOM^mD0OkUF'5 ~ZRӍQc6Y)vB(2t?9]+YҾֱ=*H):8Vu٭@'Šb6›Ȇ)u@uu_bV[=g6RhѧZeWg3W~>Ǵo)iqB>kӎRх&0\v20vB2_byo3UMx10zٯWzlsG=QM9W]r=_|iHC?nXm3ߵ8o Բ _ 3U#aRDdOjt:ؒO|gP*=oz{`*`#b6;E0<6Z^GoY7eX#m 660ڕkCVߪgR>n.;0R ؐZ}8y7XJ%U$Q]~'fѩ, jlQ܅W]S;S['Tƹ/=)[ _K1B޵27=`2 LPu@'*< R@vy(I2\Ҵq&_B}*ZW2aw3Y.HJ C{}1wfGOMiO_bF,xEQH@ YDw^ +'fG]+|N71R+]Vܮ0 ǥBz W9tj4dx#25'|)w95%M/1&MxB9Y qb aoXf-x6Ti㌰΢~Y æ鐌Yr1$-7Yӫ Dy4hhIvK>.3YP!,ZL `eitQjZˢϱ]~/grCiAg8o=2CC){* ms=;*'@<*WцgfsB]U+y鈊G)ɲA"{Xp,T\7w.m(^ͱs*K],ԸvJ.۫㏦ңDT1ٓtAkPQ5O?AE۴!|s qé伔;2&oiowT{߆Y#nѓ]Nτ+:b~;4a]T<缤ힸInʼn rČô5JX 5]HOͺlo.)S[>u?ۉX!"?׈躙@ )ןX$5_ꎾ ci79C0]axިblɢ?)h>Y+ٵ99'_SjIШwyv99tmgd)ַY|BqI MnS^Z} `zV H>Uf3hC!Glxof5l*yv,1C C97_xՖb*-`&!R1ᛆ/l)Z5~قb@ Yu1א1]Voӫ}ۂ~@AV^5H*Ī LcD 7U"uSAΥhcC-esQсA?E; I;0ޤ[8PrPUJ!t+Khٓ}- ļ%W*䭡;Vj)ވ†{CuNal'zj%^.i"jE 7quMnrLRձqXyXiW شk;:f ;W> endobj 108 0 obj << /Length1 771 /Length2 1151 /Length3 0 /Length 1696 /Filter /FlateDecode >> stream xڭRkTS2ȳ"U*!%H1ThxHE.!g&`0@]( C PA[ "*UQXbF{J5{3a|7 Slh$ %@  too/U0X9b3$ U2TKNX#2T(OHRP |\Bp$vr(K;N*Tx(F1uS0&=$%~LNKl.I$*@ akz$$T l??xT$@6]ߛAMNg *`b ntOw{J a $r8C ok.7t͗SdDhj_5 U4wNaaڰGPL L/ *h`2A** Tw WGL2z1U<Ո=FT ˧^WyЀI1IKP$AL1}>"B%]g+KoTZ*w,vFmm/>eásFUQ>ʧjd1oiIp0&vF{q[HcK_bg#wMnU2@g%67o\7/@?:HP|6$Ffw⥸>G-:7, fv{[7Uc(~6ԉ<ՍV>ΖkRtC˽3,Mת<`hըff_ݨ/k[/SQ[tm~=aT|q4Y.ŐTf|S{t &ھ)LigI9QUPhW~nAIMY.3է/ώu<`Q,M!!)cG /e_$kJ7[=suJy1hmu)x{팜nA/3IpINՙ}k35*~m$^diE'C4Ʋd;ji}TaՎu|brmٍ92 Q5ʡikML<qʄ{m݀o鋚cuږw2O丢ۡcNBlQHHK}Rȯ:ttؐ9iX1&ylydV~ q2kb"ۆbjd@|^ק5+'c/tbƻ)bB ?EIܸG8s=} ճ,. y᪪Cu'e Mw|p9+|ɶ>C|2N![o2Ùq' tzT]^.t]>ͯf5NOV+2ϬzSw`sjeq'mzd N9]H5^=92~^vMb= endstream endobj 109 0 obj << /Type /FontDescriptor /FontName /ZGGNQH+CMMI12 /Flags 4 /FontBBox [-30 -250 1026 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle -14 /StemV 65 /XHeight 431 /CharSet (/greater/less) /FontFile 108 0 R >> endobj 110 0 obj << /Length1 1055 /Length2 5003 /Length3 0 /Length 5676 /Filter /FlateDecode >> stream xڭuXTm))AJ`az)R`bniFTNA@)F8y{}ݟֽZkm6fP%Lp?/G&p#O,`,PYbW\XH\X tvغ8~da.p+ @aexܼ@( ` #% Nuy\\1dr0"H7 &j"1`-?d;pttrw4P ߡhӀAY8d60LpWE wX[8aE`:GP_E1fǧmGz;Occ bUKa6a7!f{0$ ( !n+LOHfB@!!! ď   hb /B0bDȿS"¬lH.?1\B$׿`LsB`?/'0m"`'poavl l "BZI٥|(P)ƒM:(t%C5gQHpט<]twS'<| Pߝn6~8[/N6|~gVGu[z"A/2 3,չ8J(I6z84.g~NqtmzJ@n$YᦄKoˏ$#쭐Iכ7g&@֥]?$8}S.c\v,]JQlC'_w+!مU%igFuV Z'/,Wdj= !׸ka@#o[-@ʞ~ ^ N W" ЋpZ+{G@BX͍b-mz\GxQCSgz{鶷>-WIwpKȹT$X) %Mc9wn%\ ɔ*yXu䤩oQ|5q-+Xf=} ^6]Msk͌z7*I1td`,Fx;i>%c)/5Qܼ;hux%;3y F |ꈣ^uC u2oߑpu`_#ZCnPKF \Vfv:JDűV/K7VPo搘vσ2O-*4|~*~Ba4z"& T>>}S\ZaɒWPǭo؟|vغl 9]~]GRIC^:͵$3M_s̯ \h-HBC{R ?91 }pjVBN6P*gA.IT!Hg.r%n5qP@/^z*dqWbC^ۚO*/W05;2bXcZl{ܶ_SPRJ6KQ^Y c+ҹVlXz<.0c8~B@8_Jfmhz6Qlŝ QKRTrbtKAG9Ȱ%rAQߵ v-sE!ΜqA#.+wInmVof:Zv)00>iEzI.7@:s\#5{DnNB ٜ)3uV'd.ٶ"M<58*ӶuR˾y"T=mV έM窛C^`])f$ rf;N[$uM9 )p8-$bH5k S=LA5u$F:tqkKzpvCn^h(Ş`Gi:'"K2YYob]"6~!N11jMm8'b>وȗYnG7_z I#ܾQeMbP@*ͭG3B:ǖ eeXUJwhW 0\c|0cY>[ɢ@ѓիׇs uՊ/dPʣLaJQ Dȓ yF^wWb}U]5\s^ '' )s4t#Ѿn<${7;n=Hy"[1\ mX)3L WZ bQ!n5LJ˃5%ԂZEیq(x?ooȽzs8v6eq.B7ytw+䢀vFO& tVVfKB8e #ݫީ6ʲdijCDcoG=?{#3-0W &0KXMԯgFFa{vA3+.?)É9 Gz=pMPDpzЊb#6GHw1$&4l>qHQq1IL!k3^r &$$> jG[7:ߐ𢻧Y8e{Wlii༮syyS!x'Т#<?-&h@J 㙫[@oD2CjZ _-SOWN#E?VwjkpߨF}Eps"vRw.]AlX PJJFT$'|s`3E$d1VcCfmU?V}zqypEՖ.NJJ66V-Ó[7A3l Jf^--atH<|rt,c}g:/]K?FDκ] =m$'mW]@3 sU's_[?ʲ<8O>匇2&@U&{rp.(FB'm? R,ck5G?Z=F4ۇ "ي+%Qzl{qQMmLG[H Ĝ,k+l=9reB=nDIk/lfEiU|tPJmOZ> >!PeƚARZ1/^Ǽ ~"B:n* gQkC6{}~$NrtjuHPk-ğ6 << %[2I>ڟ, Y M3plRQN\˿dðϿd (VN O͵K2hhj9C&%\ω~^%s'JL`^fSg<-a='g//%7/|8V#H||D (/e$%-BV t|Fk|wMV$di n?:i$JŪjPšn>t/hw-1yl>PdË߻MN*-D~=uB*m;0_ mwAnv%] ǧtA*3Togv ϫSmD]gapiUa:5,Ac]9:Bd7pmc1DFFH1?WȂZ1ˈ+ynj5.a2W{4C50YX)u =l74qW҇> endobj 112 0 obj << /Length1 2052 /Length2 13697 /Length3 0 /Length 14796 /Filter /FlateDecode >> stream xڭc|߶j6јݨbI۶milm{V:ff!:hfoeu N!hx!ȸ_7 /w AqcT_R{^XՃ2zKnл:ك?Plb",Hl(˝,6miG nU0ŎfF4ez CH]T۞^{3Uۮ-cֆٛvpⸯy T*$`Zuݩ?985STk(YIВ슃\b&~x[5Ѯ\ڴ9aF6<1 L6PF%gb9Ěb憷=ҽVgGd\Xj Vvr[Sրr'-KYST Rַ&  "^"0l6k\֒C*ҒC^LNcFiJ`ö $Y5gX! dXr񵂝ʽL#!}w?{ޜ0607^Ae=`(sY:bҵCX`<YZ5^EP,xUv"_dvh*tO7ȳO !14>o1%5/f"s%Jf9(Dv^"E۟e[&~z2[$O,(~ɠl~7R3usk9ԶO:(E/IC6<$D_Ktر'q$wyq5(l݋[U˥Ωvpvu&,WX"N^$W}NV {y+uଣj%n%5j<}ս)Rz9f$%zVF+xwfת`~Tl&~mKS/| A|Tcf31˧ɭB:ZyMEFN |$ydmn-qM5qGttWv_Z1dW6F|lf1PfJ &6E;ł}{[ +*9۠Y! ]Ӌ^W= 6UQZHa0Jpƻ;IR(i-,7F**=Q#/XJN-IGA ]Br͜5-rK:[ѺopXc ֎7QϒG' ŕC&*꥿}r ze?rQܶ^zUu띑mq f,"u-qbcXAS,={pB?JIC8AvEkjs30};<~w/~aH)F3r.gE8a݆W$zr-?8} %ujZ!+$loj~ZXc2R+} c&XB?ls,44Z~L Md2J˂2@sPCr_Mp𬪈*ʪs cy$LskCCF dbzy+Tu*Cvh(2I\K]6lq!ڜ%LQC |~&Q1| e-tX.9Tۧ;ub3Ghtg+%WT.e`i}~AEW Wr:mP/i',Nvħ5[;?km3M7^Fޭ#rpF ~Fva(hU[@QMtzvu .מ=Ь]XeN{N=k -=bSplԾ Mr|h;yGNIzIVWnd@Do/-wJW>˖\49-B+PB-{k5-bg|yu-5XEg8=1;,">XvBќpd\!9͈tzpܜ/7:_L1&ڍ#2{`LGUF1MaW.[_{ZdZ6PB ǯM~?XkۀS4OA+('Y |2Gs< bWԾsŰ7QbRF-W-2V[$!IQś[{LLr.rv ֽ1I"Y{F]nq  zy gkp{ qJ$؂+w/#E\X;HSm\,?jR7=ʢQ݀6ltw_ls:NͽCK0Q;Y$垦]G8oy1Dy-Su .(M^|ByXnm,sZoD-i{/!ݢRp)+zN1lv. kMF:L eьH*1# 읧3TΉ淈4)E~Jjr/8f Oh}oRYbѹ%ah},fFq3RFMN~#c)FZ+ݪ:BI H%T$RP'(ծjda4m'q6v8ĹRsC$(5Q'B^be2*9<#mp#1V z77j,5Z|!Ng˗1suh.0饸Ԇ)UY(]hU3-b2]bNcVNrp5KV:!( O5{niW9ʹl:`f8D/yL\˄eV~w*;%Z 1cУ4{Z[0~#f`ÔTn`ε{62#L[2_lSҕ]LF[qe.4_%i5Ǵiw6h9hgKSQ߾+ϼ( *3";V2=(t$iRn n0 mv,]ԱSd 澾3 isvùJXWH.3)2njY^YWlz:ć6K8饄I^)J=R)n_2>PE;?YsqtG-y_֫+,c_R vނZ~=NPuy[K0$1LF3C#m:gbְi+RYWyj%~ +bIk++31#t;;T!EePf >d+Af/Y̱hjp'|~nҌ~k^|G6E4̆QVyn-y0:gzAlvs@ŧjHW>e0˛եT-uj:HO8X L -$y\h QZk٦ߙ<}xU4ʝn=ٮ ZDԬMYU:oћh>L {;NC3lLF#FMY e[98U i^'EF ^v/EKpS|6KK@qz@Y<ZTzlŚIЖA):GD"b'+h5$ .,ySn@#9g!:e.` hWuڂ§{r5yhWy?<Ε[^R.$kp^kuahkbsү?` )S~Zk6m_>}H[ W]' )xWWJb Cs[jioji[!Sz#Ust|_":}aXH0*6=GlMrY[Sl[&o\#u]U LuJUmj×g׏~ x7( va<202'Y<;:D'ǃRh3>w8Y3~ XzzLkyD[`X!$@-tkƣ ծr[<<ը&ăQ7Td!b~؄n%o^x&; C 9,1:ܪI~)k6]g> kݬzHϩgi˳cdɪ`*tivRXWPB{ley%@r\wai9R18NeMLEUVz2̰^3Ed.ߔ:*/W7Tٜ({CVe=`q|k4}IcYOk6nm<r~ÿw5jx8=Fq6{&.Y?Y3CJEpEG2YT*SHCvmRV6'7_c:W2wfgUfL}((~:v%"J(l.b~P`bε;S<}|rKC萳W=D-s9Btr#l<8Td^hb[qbIE㡯_ du|Lc?cI'tePCODO NIwj Fsvk8@Ԯ* ǿuznFO&(V9j"JpBߚ7**Jf#e0g G'Qq[>MtښA'4ܨ~ͷ͸ I( &h^*|w|HWVJB>$G \FH;ZKeDbixTlD+Rm 1UbvfWW#7 hT^cĠ Ӫ NdÄ uJT 59AkkU͙Y xfL/]W i:}ZsN \kP>by+ vei#/hd_䨝&%z1o!J%KF9S?Y=Aǭ3"WOۧ8{Zԭ0Cmimf&LIN̻I槂u%_5fdqbK1-Y+[u״&61&ۍ0xqVQ)MBB#2 9 {=yrFm:K`hAƦiQKb3F*mJHpG>> YM,n=&aĿC;{nCЪݔH.M⣦m4UDSYAkì>xG~QDR.ip,zDxI@k֖6SۄhB}^ɖg<34-NR$#^9#!V}Z)۫h]ܸSd(AOgˏgr'uw|ԢQw}Rf[[,$ɣ`. 14̎L W,u }-囹XKu2g|Pu٤]`!aTD8/9tp` E$i6 4HVNrp >{" znf1o;̚_<$窹f؄I}8aXPnX>Ǵ}n3M MQMPXt &}b`|n61|=`Ȥ!aʸ5rFx[hpD!g.Υ1t+F! |}{}H1c%;^3V\-Gˮ(/^3[/d좈~Rʟm%[q.rh14wwV¥+x̆)m(4#@!uulfYe+o]IsC}ֺoӒk~ 6~5 *AM[NsHѡN 5&O .,WWQ(sS5oZ %_IO´ԕEiK(HtwCAIn&`'Hs53dsҵ}jbi'h/T3>FrS|`i QhsW$t-)>a*Ԗidf.G* LD}dY9Σ_\ Viq,.T0%J z7N}pҟ:*z5y,Ȉ!ȩgBP#Z,E.g`T|. S(Q~/o!jۤJРB *JŁzbp[ \^4' eH),^Q$C|-P߬6 ]dUL0'n6{fYh"+a>,\`])1,ˬNAꨨ` /B-U`, '?P1CFݮ_V~۶g-˪wp=ho:=k-(qע<5@?+]ЉdzT< ix 8'?5޾:+|ܙϨw}3&㜌)' TRIӶȸ}G)zRD[(%;\;?48 #L@Xap?_&|YRd)` Am- 21FSdCO&^'b;?niH1ş>L[}(T٨IҊ>2GioLgфlIu5'͔ (Khk^$6w'k\1UavEI{R 47DZ=2cȓ=URΫ"H,Y-u=Ϛ  $U p:6n"[KchH*pP2P%UsWh>t_w!"7ԨVp M)L1=4ٟ٠K|ҝGy KTU1 v|ܪzWZ$ݿ9oIU9BUv\jOt6Q**BZ{`(Z]\B3d3_`I: H/\7Bq=GS(j܌-Xȝ -|'snL-qƙMe R7TZ ppr>yl΅ kw`|mߤZ! %>[ z__yWVkcct|7('m4|eJO'>;ӽpQ(ju=czz+KU݌2^)V^91Rrl6,P,~x-SօuWb~Z~Yt`46o{rI&U4}_ 金7f1;R=9 (_ԑ0s_oK*bcԕ[8=*{(R8ЙWIISP\}О> ]Qʵ9.,V̜[ҿ$ wblN|P;KHd%<0B=Y-EV$3?|rA*BbL ޓ&w-z vS@v")Oe!EGiF^;Ƣ a;G׳Nj&V(#ͬ{Nzۨ&8~OK, ɨ0wH:6_[kaz?&zŠ%~tTDYZըH$9Ursӧ>d/UVO6 _4k1xj;Ol_v^1e}v9b}>pLg,|ފsAɸ ~5WӂEA-Zh4I;9G ?lv1. !B e~.2C/'L"P{untO1 9s ̎)%کR$g9LoS,5M1p Y՚$2ĵ :j$Kb&Hfp\Qk ixs3Q7-OPH7W A"-N4z)u2]*dug{k8a6ck^m fک9&X6A;}G]erd|t?`{ZtY&|YwquwgW=ʼ#aU׃[i7ST*]eA!͏.F򭗁sSVmٛb< +$KOg]]G)" fT i\Jү?K-{Xk 8?0}6".ljkQ;PALEߪ#ECd-eWSYs{WD/~ҟ}̈́}u%5r~[b\M@#eB>]_.2$&Z뜱{:4T/{5VԶ:#kNH:N4>dKQn3`οJʼn-C%{INEW*63~ӏTC584Öxw+Rijzsf+}ܣҝ&!ae{_y[Dj[sߕQGhɏBJ*h~ p7' rT^x_H;|!-Og6ך2Gdg  Q9DySոh2&X xZh)I"gi?pdOxWa) >fp*SLU GEDBllkۛ264U =p&$3ZEJ;SIO~qJ8`FmSz}ip{9Gb?[ض)W~l<D,qp3ᨱ]  W.Z+\4l>Hk_Y[Xut pRY| l&7I;:gg?N3|.xH9FӨ' 35qr:/F3ǤԐc6^qٿ;#mzEϜciQ2~(SY~؎H5Z4j _2sڗl^.IU2x'yLm"9{=޻#W] fi:dpng-X\$cFHI/pkqK G?5IG,/%RTLo+} <)HB? +#Lbox֕"~1!嘶d>O7jO+norb']@vjz&>SxF0J:jZ,t!|<_B*ԑ=?E.-7tj!**1.D/ǔÐ0cGBIM"O1\B2Pag Fj$Vz 2~kӎt9}2 XAL~0]6K{P5Q'%feLA@sXՃ@o0ƞEQ)چˣwf\D|Hf\>G?T]C ȑpZD| #m @ԥ۰Ňh!=.Ɵެ?z՞wiM <3 Z_ _-iv+2`G &-~qhcF.;,׌sJٍmpSgJ笣6-~!.T :lϽp;c:0L~8l?KWG҅v޶wB$j3#-A7 ń__2_o8qH |oJAŁƵ? ӮIF0&m2S_w6ɒNWÍ_[C )bNOb B݉? !Ȫta m1q<vʩi%f>BSEg Jq[0h:R9V)7Jؠ>%nAs%7&Zc~-:6xOmo ”V0jCRwۍa6ْ6pf-/q(菐͡H/㍹2E#yٙNrHBB47hTt;?[Mh_i7U]ɓ}k=-NAEoe UKP8it5Ԑ_nWbZu uW.aMJneZ\2Aq8. #QÛ7=!  0 ۼa}$Z\P_7vΛyuR1<f+f6 _$SN +49-rdp9m͉(LN1t=åeT"}$xג2ь ϋT,aSʫ\0j}0cJtw4hH U6K$}C6=ljO=.um:zl klMm7X+Hut7 15*sAH+=:MS؝oF$ m[^s?퇬_Mq8& mS[vaTlOy7|`*¬%s<,TY#h=t/p3 RD`Ns5C/1ƭ+𱉻z<5 i]ˣDw#,0LILXq݇W¶CGruB;Z!$ׁc{*%o{i;%TZ3si0l SCSmw&>5+ :%.M1bn4Xh ѐ %u*'.B8/!4ofk[Qŧ ?ZnxMkD1- :}] ]9 aܳ+^1׋JMxoqZe^|}+47{~A ;H0iYV9y-$9P'z(t6Ńnp` ,a~x/"pqmC W ڳ9t~6;;4 endstream endobj 113 0 obj << /Type /FontDescriptor /FontName /PPZXIY+CMR12 /Flags 4 /FontBBox [-34 -251 988 750] /Ascent 694 /CapHeight 683 /Descent -194 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/B/C/D/E/F/G/H/I/J/L/M/N/O/P/Q/R/S/T/U/V/W/X/Y/Z/a/b/bracketleft/bracketright/c/colon/comma/d/e/eight/emdash/equal/exclam/exclamdown/f/ff/ffi/fi/five/four/g/h/hyphen/i/j/k/l/m/n/nine/o/one/p/parenleft/parenright/period/plus/q/question/questiondown/quotedblright/quoteright/r/s/seven/six/slash/t/three/two/u/v/w/x/y/z/zero) /FontFile 112 0 R >> endobj 114 0 obj << /Length1 1012 /Length2 3712 /Length3 0 /Length 4364 /Filter /FlateDecode >> stream xڭg\{ǩR.EXzT"H  ҫT &JD@AzUM"蹏{o;ۙwxա(G6 IMSD 8 y) uRHVQZ^,C-ht$Qة):$v|+uIfg|钷R_Nnу tz`o*Qd[m͗)&xl_6eYig nE1O,ON$IY+6ze<ʧI:ɥfX'$.W"S Tٔ'`!s x6 Mmf&0voFל gN\I78nz>K}F[f8NfUXe-8t^onEeF|g)1eiy^!"{Z7u<_ Mv6HIK90eB[վ6(w2[8R7+_+F?Ktɫ{Iio1i]U$Ú *J Nb X5ge"$-)GZhgCx[wYњ-#Jkv<A5ə'GigHo h? -%zT.AUNS!f] oiͳQOa)1. ^}|je^+&&ߵ,S]0[xe׻M##[p @"r9vzG g@@ŀ{ kQ*.D-s*Ͼҫ"dyK ~kP}}RL'rxC6,E.+r;̍l4 pReE7N")^O߾)A+ǫ~_1qo266`]kEujۃIwj[ֵ’zV @#Z7ld?xwVҽRZ@ wMr'Up`its 'KdyS 9M2e62>l= VKFpW6ݫ*>ܛ3F1?nqRb) i?\a>O}kO ,ק ;qY[5gr :R{xC/CBy&;~ Jc2\L,&'Z|tVu6|ٞE\dyں:X14т?wqOO}1{6`p!K-P!υ!-jH \7W8&읅2עO+ѝˌtnVMGHEG&I8pM+)^њ=q#ILv [AE TUI9>ӗ<'Ioj9a IϢ5::)Bwz eʬbjF: [^Iw㏟t<5v 1 xgfO;r4_̥B<уFW\#`Su3B7əڛ+g2癜{#L<5w?dGNa23;}NNoW읔KF%Q6t6V\FY)FOcv^eK\Q[G$}N=z"߇>F2ɬdH]2?+R--/tl|j 8cHXƝ&3,ɈJ5G|XLTx=IFv__؝gے_#/;e&0r6cNۜj)miax.T )1Dzo}9S]>O=}`hzB.~&@d(Q)t.ei-Qs(7ىC<]#]2CWsl Zfl\AgqX#3E[+ڻ]2CXn%M/JoTb\pPaU~~gve5l2v$vR9^&'Wcf )xnfYB5nծxxTfz"4TKsj!nS*oH/BQi&=dKXn} zS#1g m Y{$-$4*CCL4ye2;CZ N/Sq\(|,d4U޷RWCVe\6:qX hHޜNǛT%w~i*T+z9'cZ咥[7">D]X/z+E8yZKdPx#s>3MFOo,ks +R3cmhyIE^KbR ;Epo٨&5u6pN޶'w6]55全Nw'vW3wݚ~|q6<EyhLx`=/uw ټIaNzHLkn6͆-t+/\uטjq4$R tkT8uC:0EootG v P:WڝDre{Jiv[<2"_fIbВ>^9LHm{Cq_*>tslIlHU,}xyaFDfSv%]h2XuzW?iy uEV0Vc naz&-#!2cm$g'Ҕ59lb%&OP哾{3Z]=ʧŒ1g+U3^ixU:»5pa>B[njތ1kǖ8l*-F1Bö_c$Lp{LƦSO=ʛ:ܠ]gyy zڱ*49zkr|u::U`[3ZՅdI7 -9"<"Tƪ } c-tFp۹#?V\nٓ T2IBc7}-oI9$z6.I}Its9q~-/`U֣[x2&uZmhfrM%Y6 s:mNtN=`@L'#4L+}F7!`>5wƖuXm /=YQQ-b8\Qw\O=eS*+Egar5gulD(s;rz\8ǹSޢ[,Fe5}n&//$׀ޙ){R ~uK]=c> endobj 116 0 obj << /Length1 783 /Length2 1297 /Length3 0 /Length 1839 /Filter /FlateDecode >> stream xڭR{SB+6`&bl.6[swAb'S3ĚYk?x&FD)V\6G7JAYAl؏50EC= |* 8bD|:7n‘a\]'m0*pvM8>P,; Q 0 L>)ˆgC Q6@bx=+ġ<|ڇ v$_JNq1c#Ϗ FҌD;-N~K{uQ')']5l9^tFyc-~lIVΗIJlqXX9X;*w^/g}8ML0,%xȝ&qU9t+pYYSn\\(5UaSZѽ)}/]%0X)V/S448+!'|(,_h. m(kvpY3v7.ld_b+j=ߏ'̫)'tfy>I#=6Wv?ю >n5zaZ9uh[]hι{Z`oX0^淽CwtW7mcԦw-[3GK+Qwvmy)%rN.rؒZ՜.ʱWK8r-.ͱ[5,Hv1z,LQ3-XgI}_PSoK; L;GRtZltH=7;go endstream endobj 117 0 obj << /Type /FontDescriptor /FontName /VKTFRZ+CMSS10 /Flags 4 /FontBBox [-61 -250 999 759] /Ascent 694 /CapHeight 694 /Descent -194 /ItalicAngle 0 /StemV 78 /XHeight 444 /CharSet (/A/l/p/v) /FontFile 116 0 R >> endobj 118 0 obj << /Length1 783 /Length2 1285 /Length3 0 /Length 1826 /Filter /FlateDecode >> stream xڭ{<[i] *VDDVMhFH8DnM**IJ-vRڏ5zSԥA43ӝ]~?Ġs2]r43t6@(l6@Y_!(A;CĀ,@0@xWfx[b/@H'@Ȅl)cPX!@m$bC)O@l A>@ z|GKßb] A q@,-7 Bx˯7 C\a MkC `5F/zf\̄'|>]м X2A J4hw.,,4$0~^x^PX7f&5hIMW!`"$yynx, Ic|+xLXH1J@b!M/j>L{]YȺiUw>NpkVXOOٝi ]v/h!5AQ}zqذDfPCfGd߁jwRiTSZ\O|qi*̵xPuY{/W}i[,m3:"a~[Nguw@ՈA-+եE].ǁF?h?ur[yX [€a~%XWVvαdJ28xtfWq)~4cZc~ *t>kd%(@ˍ8.ˡ8_{}c 3Ե:Y/5 qM'9W.nT=Y7&mTVJwސ^=_;22s-Zuߍ;gV \03(DbL' n;ؾ$e[p:Yg' ̷_)y{㵷[Jݮ띙+>ko=$)d"퍻mrꞢPeԙmE  ˸c CWY˥tdb=thHu_*QOSI }F})^$/;Oc[Ne^o}Sw@51fY5f}e0!֫Y5 y{z%:IZZ("<yB瓑&m7FB}$+iYK|lF?t;Q_7#'_ l =a9[uj8\^0K'ʕf٤}\q endstream endobj 119 0 obj << /Type /FontDescriptor /FontName /OJMATN+CMSS12 /Flags 4 /FontBBox [-62 -251 978 758] /Ascent 694 /CapHeight 694 /Descent -194 /ItalicAngle 0 /StemV 76 /XHeight 444 /CharSet (/A/l/p/v) /FontFile 118 0 R >> endobj 120 0 obj << /Length1 788 /Length2 1392 /Length3 0 /Length 1935 /Filter /FlateDecode >> stream xڭ{<Ǖu)S̍jb&\3? 7!$e&Fe)2Caq:D)4X( {~Sy>yں&1~=%@vPlqCPdH2ِ Zx""8ong@dvh4 F+&@ 9L: i@0A b+'w0D L:´gaFDT$ Cl 0@օ a#X,ZJ?dEaFpAfkA3-M}\I'A,}1Q c?Kipp5B`=l4&ĥFYxſixBfpyn/Dg3fáE#퀕LF`̌@l.|9'57Ъ,,/7%lʶ(&f0H1#8%W4'jON׻dpgLH;Iz>MXx*[RԦ=qY[w, Y'k~0Ph{9fK$W<鵛N~>2<#7P'z:vV$ΡDfL-PlH`­B_W =Nx_舍,ZHG̩+ഢ>T7\;%vK`|NWzoqS#q=;e0D۲xئ*[?khRZHwAˎ'7h!]dH3&kk7оLWCC6 yCD3;ٵ>C8Fu*O4U⑚+ž9iM~(_*odᚢr[-5u3nU~ 7֖.W>>r]' jwOn#zKyJɢ źq] M)09vЦYqD+R-ȸڔ96I0$)LS'O:Ȥ ,- A<46*Y_th> endobj 122 0 obj << /Length1 959 /Length2 3511 /Length3 0 /Length 4137 /Filter /FlateDecode >> stream xڭy< kv*%Y;Yo"K cf-]dא5"ʚR(B$3u?}~{:9爉X0p# / kvv`y,'/$&CH k`uu@Te1X"R?EBЀk@!(ED9@.09&0!xD3~z2E_aؿSp ˦@6 àQDĐ^?lY,kR Q*0>X<X``pO/spϬ)BBuў(8 Wg$aH<q_a8~9]0>`{K x;"?տ/ǃCgy|d!fh(D{ *C&e*@ap' <<pcQR@HA!e52aPE o@PyJˡ~Cr/|} o ȧٸ [0Y ~GOC**(*`@M^dP:}+H=8ib={+VQaP148˚W-ao)Q/}gr~ lov7AS;a+lOGV)Ff=X^yh-i`D?-BPۑvSE(uvxEJghfBn34iː}ЍbJw'TA/A/۩j3 ͹236 :,WY/u&|ls8Pj[g8L_tu۔|"NYlOx{Kma=oױ3P ۤ"SN%=d-ddle(1@ β̕xĹR^,¤yUJZ ;vE}YBέE| lJ0Uԛf%c>W}OJ[^\+nH NH{y[+{p32PR|'TL2 b)\ʴ96ԩLŔ^ e? nQ1\gCu&'w b^6[; ,T_ib*pi6٪#.·_ϿBi}Kq܇>8)4;5nξǢʜ9LPG}Mi!ed'r'g~<)o ͳt /*#>z\>#SZ.ESy(VE&ցt׷僺"і)g :A͈XzAT@ԙT)ݫ'̪M_gzTSgyt_Q$Hp^TeF뒅#lQa#M#rmoK F/_9OHs̵̛uk/Ji?uY˘jM4@ yLO'7Y$Gvt^|Acf{.gƘttԚvunl^˺ }@`S{ʛO/gXQM;( Lo!gz8Ν!]:83>Knd"<7SW+%Y#\`ج=$/JKYU[=>4@JJL;ZWW/QTuN=R: $I3ZE+O9OnX }lZd(64Ie^W%SCLNF:= ^2nsy$e^h)ahK$-G.SH#0l8 mDr>ޞ͒ zޡc0c "uftf5gzbu,ZZTu=ՈiLc{ѥpdL?NK Vb2UeK"íh| l=Lo4}l `eB((VV)r7KB\x㮏9Nm_-1Ov>mlz|Ga͑O Qf.iobtfj 2M%@s#YaVU]jBu0ake$jSY{anP,# %3%M9_n (**岔.``U-'Η|"-(w}Z08j⣅; zR, F ]Fh^44Gu.UC&Y{ZxCH*/kG{.{^KS(?\Ra߯~}ܦb7 nDbMuZsE`㙘];]'J<̄誖so\WJ YJ ?qgw'"-/Q1ę9T0m=Q3`rɋN3.(>I]' ldS$F\ܽ%dZ]c2Fʤ~e۾r  BFt]4|e-{td_bT6Ve~jh}^xM' Lk'T@z=`:Z\hv6eڙ"Di_/W`ˍ\OKhHRY1Of3 '%zO@@kTdH~a*U"3eIQ1-vqHdX*iJ=JL "Κ?H4/Yp'-@%2iE"za`plZ.r~R?o.Aд̤9\019qa͈m{7 jE"{XhtԿyIԅk1Գkϸw%JP:vzGr|{' q,o[%U#6BRvVX!xb3Wlw{b|&W+{DUٿ8] C!}~gWzA Tdfc$X˙+TAxUȉUE@Mi.W2TO:lZOѦNPqi)8g@qZnR_T́$6w9}:aŨJhˆ`SzE&MW9Yt7'LtΤ$*Gi;(%o&jb3φ}9DhAX9suƄ1YEz×mfW䅒ǫK݌sżDD1Z{8d\B&~MW5{=u[Zn RlgSyW7yLQpNִ",b/mȄftjݲ\·p!t"v+nEdh{{)*A/~I}m!i$Kb}V/M?vZVf \D]8s`9g>tlؘ=¥!Tk 嘙#GE,V)M%](4g l4MO@К"rۇ~/̂*QեQT+̠[{2`ZZX*u8̓GN4] nI39sQW:99d#e]I=!gq6as;iڂ{i.]6˼``olF"۵9^O13KM.I|3dq+7io) A8bߗ8CaT$imu#cP-8p-wɒS\cѢ7l$Spi+1l"끀o5!t6 X='䢯77I6(dN74hb5/Tg>7aIXkmL: Mn~u^{p75&z{ǞL2G>\w5]5*ꈓb ;Y }1D endstream endobj 123 0 obj << /Type /FontDescriptor /FontName /RGLBWS+CMTT10 /Flags 4 /FontBBox [-4 -235 731 800] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 69 /XHeight 431 /CharSet (/a/c/colon/d/e/g/h/l/m/o/p/period/slash/t/v) /FontFile 122 0 R >> endobj 124 0 obj << /Length1 1444 /Length2 7780 /Length3 0 /Length 8628 /Filter /FlateDecode >> stream xڭu\TkSr(nIeap`zGw[k_k3hf2"Ummn7: t;A"naan@gȀ ֖V&濂R  tjf g7@ ' 2@[9LA)Rt1C8D`"0`;79S ; SC٩*hom`{G3P G*j^EgIdalfp@AA6pQTcShoտf ` =y3^9ͭ`7_@n谫#~7 sr8a)L`_S)pK<N&!opKB\NxS7&XM vy8uο01 h/|f`;] _# }_ `MY,@<֖O 0i0XC&w)^X%_ i ]+v5 #l5{(dn[ `wqXsNv@'?`N5 ˀq|_0;OCii;7?@@ 3B p][XrMDmk _!I[EUO`F+gYԿ-N!Fڦv'w m;{4d;Ž\,Emˑ*v!?@aAnwϞ, &YEg;RRt?VMz_4mZϺp nf>C05y$xkF)` aR[T]rي^uE;`%+qA-ݔkBɍ#2f2kV&Wj7$鷇VSByL2ç*^sb/37LAVnSր[YՄMdKXcRlcȪ"$6J}`g9˺aneh%FY]޺!V+}Nmn$x182< l[1TڒX-}$=\?.sjL'~;>`隨:[\\9=Qb_\#͸F!fWNhxi ֕DV ?Uq"Lxͧmit^܉pQޖ0F,o夰~zXwiA\t(]0HN(:߱[ mb_A> /$:iLڰ`̝{eF+p Hw".`R'"̇^g }\U衩Th=DϯyFf8ZJg[3߶@Z(7oQ.N5[:~g`gS7xMSLɘ^/?S}j2@\;Ώ^3*T, jr56?q'/8ۥ8&Mp;2~Cuh,| +![*xk?~MPV8.k9Sy6 g-Ȣp7$C4CۗvMlH!m:?0O4ROB~>E\P4-^UL͸>Vs5.ˆ8!١ m|;dZTs+S3y%db3?ZW.Ų]یV:鮶5hQGP3˙OY^.fxqXS{ѹ}Z2Kd~dc~rEbvՕb9HS{%'$MV7]WFhػ $<͘c鹂Lr_]N=ҟRr59LڀxdVv\ 2E\rM']?@RFłi稀ZAt*DN)?t&پo2i1p=ZČٽtIC7徑HmUD(j,&6)$2"d#a <~8y43 unF.fpT΃Ok^bw }T}7oz!ZOXvrX~1+\a ;b-x ^qP#j{#r+qA@vjgVEUTC8]9UOM&F+IT J.uWRqdl׎'(-RިM[zNDRC7?,._&@J)ffgQp.k4jI-ъ#UhUlN͆uJ ?pvdϝj5`SVijwԎv>+tܻSB\${NY*MYqh'j/ѝ|X؄mY\jCB_/R?pdo-z A/!܀bIԇf3kN8~ݝ֍kS賯Z!f)Bxu',0e0I n^*E_\$;@:&U>D<ƄgYKńn|HmE@r!os[Hi%:\ϩO\!P͍ hU)˜O\łnzH)l)>U)sV/ 7(<4[ 5S%#>ݞBuN4D+vC漎 :Ȋu9HdY9U;Tَ^eָ`rިl'm$,\`M$;JPwF}A_7 Gc9 \&0SH7kβۦSZaPC+"YeEI gHd){sY8e温9o5#n닯uAbKaEM5QX^g+A;JmGIFNĎŤvLomG{Z=6)(J9h}Wn g0"@ͻi36>5f9MCZ-)Qtq%&7[mV2Щ-#~rUtLZ"=5rWWta|O#ٛ5Uז,h=Q5B5TX ph/;{(?0;9t/sBav,ralCj8Jࢡ]tgFzQr"ArlWihnq}<(#Yd]iҧ|#$žQw'si34|#-܃x7} <`_dTA֖xx.!N8ϐ1C#t* ?e`΄ ΍/btfe ;}C/0Q,XHnνJc [Eϥ~]ɨ5FW.ThG<@Iؕ"(F\`hc9+zcfyhߎ='uη^`]`zyNڕ*`xHb ~A\NQiUPw߼RmfY۷OZu𠟤HةrZWtow` ~+ 5%SF\ځԽ^{;gQ}ti,}LHu@K#ny?G!x$.[(G`ޙ[Qɞ7"EɖۂZMNZ}I(ݘQ sm^>4{R"j(Z-Ѐ^ qҳh4c5B=vļ1zp"Kʤgb3„r4ZYɑ,ybP5x[-2cb3]'ic9^=S'ƢUw!2ٖXHUQip&%<^Ao۫f(jzZ,}H)hƔGKpAg~+pJI&+n&C|*iHAE:hPH%.PSN ~:I1GMg7_1;eRӤ,`B<" ]&`;Y+a*F_Bۛpu-|ě!nG%)|1AbdNRTfֶF픗 Z_!>|h?%jKMD;y͹hBy\bfTǯOh #Q1M1S%:ƭb?c$L_M~/:(ȜƖ}Br,gTd~% ]U;P=ԁ&ѽG0VzJ$|nƑGjY{#Jy4m@A4S$S 1h8_Wyg vB=HTby~AxK`(xHJwڠ\cx3MLR3 ϟ?v^+o#Noc2ˉcB )Կk؀?RO\ =?nRt&B+ߨګy3 Q-֞`Dn]{h$%"?riܕXAyTvyJ a 8F'g]4 f8D\;2^M"<^Tkǐx1(O7_ӞQFkC~=Oo[N>E)P[ O35j{`Mg-3ʾRfF s\b|lUT>U71ԬZ+蕊D qzDjrU+b9P A/)8u*! \RXOʇZ/0{M f?Wg#rNmazN߉e _ Wy%\0yhЍ9_. #}2hc@|9Dv^_US ھр#L,\wTCJq '/@L6 S̱o@bf}*2[) r"{[Zql7=j{QS0x`tFHaWqYeE<TR=CnyjC=:/ T"*]G6jAR滛nIES2e&˚^ȠَMWr!}XE@H>L@ߚ8𿦵.ӦCͿܻFQbэMJUL\VB%h;ׅ#ڜ$QZSPR]᤽8З+HiRtH dR+sq"Ef2D|,Wy\B`&©7kkYio4mDÊ. uS=ƻD|&w+qS2+8^󴏕`d==wW"Wq>lNڣ;]vϿs6keLtAH^&b]EJ\f~]XXiJ;hVJ5NbҞ%W7fkĆ&.4igzb[Y?Rj` jȘ#W~Ljis=zK\]4!t [O%t,]Xö;?R<ʒ< _+w 'b!u$%Gm}蕷޴I''r!@\XK ̮7] h'f$H}3 8fe~ļƽd҈C(P z*uԤ@2" E^зxj\^N.H@*慎TݣzBD| IBzaCoY|]f16PHDE*xEV"%FHh}RםKr l3ܢ4>9O#zcOz⯹1XROKf%"h3_Щ 2JM]h鸀B3^^%'2 x5~IxDwcP6~Y27tk=7DគAnNҨ0Fy(gu6#a {Erc~PrTM!~SBz$ܱG[ηh{?b7%Tt o>V/G>[#yOXIeK XZ0'xŐIs(>q3xJdn"ؽQYQxwĩ~^l endstream endobj 125 0 obj << /Type /FontDescriptor /FontName /ZODRQN+CMTT12 /Flags 4 /FontBBox [-1 -234 524 695] /Ascent 611 /CapHeight 611 /Descent -222 /ItalicAngle 0 /StemV 65 /XHeight 431 /CharSet (/A/C/H/M/N/O/P/R/S/T/U/Y/a/at/b/c/colon/d/dollar/e/equal/f/g/h/hyphen/i/k/l/m/n/numbersign/o/one/p/period/quotedbl/quoteright/r/s/slash/t/two/u/v/x/zero) /FontFile 124 0 R >> endobj 27 0 obj << /Type /Font /Subtype /Type1 /BaseFont /CCUVJL+CMBX12 /FontDescriptor 107 0 R /FirstChar 46 /LastChar 121 /Widths 97 0 R >> endobj 15 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZGGNQH+CMMI12 /FontDescriptor 109 0 R /FirstChar 60 /LastChar 62 /Widths 103 0 R >> endobj 18 0 obj << /Type /Font /Subtype /Type1 /BaseFont /VINZDZ+CMR10 /FontDescriptor 111 0 R /FirstChar 39 /LastChar 118 /Widths 100 0 R >> endobj 14 0 obj << /Type /Font /Subtype /Type1 /BaseFont /PPZXIY+CMR12 /FontDescriptor 113 0 R /FirstChar 11 /LastChar 124 /Widths 104 0 R >> endobj 13 0 obj << /Type /Font /Subtype /Type1 /BaseFont /MDWLOX+CMR17 /FontDescriptor 115 0 R /FirstChar 39 /LastChar 119 /Widths 105 0 R >> endobj 19 0 obj << /Type /Font /Subtype /Type1 /BaseFont /VKTFRZ+CMSS10 /FontDescriptor 117 0 R /FirstChar 65 /LastChar 118 /Widths 99 0 R >> endobj 17 0 obj << /Type /Font /Subtype /Type1 /BaseFont /OJMATN+CMSS12 /FontDescriptor 119 0 R /FirstChar 65 /LastChar 118 /Widths 101 0 R >> endobj 34 0 obj << /Type /Font /Subtype /Type1 /BaseFont /QWCVBU+CMSSBX10 /FontDescriptor 121 0 R /FirstChar 65 /LastChar 118 /Widths 96 0 R >> endobj 20 0 obj << /Type /Font /Subtype /Type1 /BaseFont /RGLBWS+CMTT10 /FontDescriptor 123 0 R /FirstChar 46 /LastChar 118 /Widths 98 0 R >> endobj 16 0 obj << /Type /Font /Subtype /Type1 /BaseFont /ZODRQN+CMTT12 /FontDescriptor 125 0 R /FirstChar 34 /LastChar 120 /Widths 102 0 R >> endobj 21 0 obj << /Type /Pages /Count 6 /Parent 126 0 R /Kids [6 0 R 23 0 R 29 0 R 37 0 R 42 0 R 46 0 R] >> endobj 53 0 obj << /Type /Pages /Count 6 /Parent 126 0 R /Kids [50 0 R 55 0 R 64 0 R 74 0 R 79 0 R 84 0 R] >> endobj 95 0 obj << /Type /Pages /Count 1 /Parent 126 0 R /Kids [91 0 R] >> endobj 126 0 obj << /Type /Pages /Count 13 /Kids [21 0 R 53 0 R 95 0 R] >> endobj 127 0 obj << /Names [(Doc-Start) 12 0 R (Item.1) 59 0 R (Item.10) 72 0 R (Item.11) 77 0 R (Item.2) 60 0 R (Item.3) 61 0 R] /Limits [(Doc-Start) (Item.3)] >> endobj 128 0 obj << /Names [(Item.4) 62 0 R (Item.5) 67 0 R (Item.6) 68 0 R (Item.7) 69 0 R (Item.8) 70 0 R (Item.9) 71 0 R] /Limits [(Item.4) (Item.9)] >> endobj 129 0 obj << /Names [(page.1) 11 0 R (page.10) 76 0 R (page.11) 81 0 R (page.12) 86 0 R (page.13) 93 0 R (page.2) 25 0 R] /Limits [(page.1) (page.2)] >> endobj 130 0 obj << /Names [(page.3) 31 0 R (page.4) 39 0 R (page.5) 44 0 R (page.6) 48 0 R (page.7) 52 0 R (page.8) 57 0 R] /Limits [(page.3) (page.8)] >> endobj 131 0 obj << /Names [(page.9) 66 0 R (section.1) 26 0 R (section.2) 32 0 R (section.3) 40 0 R (section.4) 58 0 R (section.5) 82 0 R] /Limits [(page.9) (section.5)] >> endobj 132 0 obj << /Names [(section.6) 94 0 R (subsection.2.1) 33 0 R (subsection.2.2) 35 0 R] /Limits [(section.6) (subsection.2.2)] >> endobj 133 0 obj << /Kids [127 0 R 128 0 R 129 0 R 130 0 R 131 0 R 132 0 R] /Limits [(Doc-Start) (subsection.2.2)] >> endobj 134 0 obj << /Dests 133 0 R >> endobj 135 0 obj << /Type /Catalog /Pages 126 0 R /Names 134 0 R /PageMode/UseOutlines /OpenAction 5 0 R >> endobj 136 0 obj << /Author(Alf, Sebastian)/Title(Apvlv Manual)/Subject(Alf's PDF Viewer Like Vim)/Creator(vim \040pdflatex)/Producer(pdflatex)/Keywords(open source software documentation) /CreationDate (D:20110130152339+08'00') /ModDate (D:20110130152339+08'00') /Trapped /False /PTEX.Fullbanner (This is pdfTeX using libpoppler, Version 3.141592-1.40.3-2.2 (Web2C 7.5.6) kpathsea version 3.5.6) >> endobj xref 0 137 0000000001 65535 f 0000000002 00000 f 0000000003 00000 f 0000000004 00000 f 0000000000 00000 f 0000000015 00000 n 0000000955 00000 n 0000001092 00000 n 0000001264 00000 n 0000001543 00000 n 0000000064 00000 n 0000001436 00000 n 0000001490 00000 n 0000077071 00000 n 0000076929 00000 n 0000076645 00000 n 0000077784 00000 n 0000077355 00000 n 0000076787 00000 n 0000077213 00000 n 0000077642 00000 n 0000077927 00000 n 0000003568 00000 n 0000003344 00000 n 0000001696 00000 n 0000003459 00000 n 0000003514 00000 n 0000076503 00000 n 0000005277 00000 n 0000004944 00000 n 0000003674 00000 n 0000005059 00000 n 0000005114 00000 n 0000005168 00000 n 0000077498 00000 n 0000005222 00000 n 0000006596 00000 n 0000006372 00000 n 0000005407 00000 n 0000006487 00000 n 0000006542 00000 n 0000007541 00000 n 0000007371 00000 n 0000006702 00000 n 0000007486 00000 n 0000008593 00000 n 0000008423 00000 n 0000007623 00000 n 0000008538 00000 n 0000009631 00000 n 0000009461 00000 n 0000008675 00000 n 0000009576 00000 n 0000078036 00000 n 0000011349 00000 n 0000010905 00000 n 0000009713 00000 n 0000011020 00000 n 0000011075 00000 n 0000011129 00000 n 0000011184 00000 n 0000011239 00000 n 0000011294 00000 n 0000012864 00000 n 0000012365 00000 n 0000011455 00000 n 0000012480 00000 n 0000012535 00000 n 0000012590 00000 n 0000012645 00000 n 0000012700 00000 n 0000012755 00000 n 0000012810 00000 n 0000013388 00000 n 0000013164 00000 n 0000012934 00000 n 0000013279 00000 n 0000013334 00000 n 0000014342 00000 n 0000014118 00000 n 0000013458 00000 n 0000014233 00000 n 0000014288 00000 n 0000015235 00000 n 0000015065 00000 n 0000014424 00000 n 0000015180 00000 n 0000015838 00000 n 0000016012 00000 n 0000016184 00000 n 0000016466 00000 n 0000015690 00000 n 0000015305 00000 n 0000016357 00000 n 0000016412 00000 n 0000078146 00000 n 0000016572 00000 n 0000016905 00000 n 0000017353 00000 n 0000017663 00000 n 0000017995 00000 n 0000018445 00000 n 0000018768 00000 n 0000019309 00000 n 0000019346 00000 n 0000019970 00000 n 0000020471 00000 n 0000027589 00000 n 0000027906 00000 n 0000029721 00000 n 0000029954 00000 n 0000035750 00000 n 0000036028 00000 n 0000050945 00000 n 0000051484 00000 n 0000055968 00000 n 0000056236 00000 n 0000058194 00000 n 0000058419 00000 n 0000060364 00000 n 0000060589 00000 n 0000062643 00000 n 0000062872 00000 n 0000067128 00000 n 0000067387 00000 n 0000076135 00000 n 0000078221 00000 n 0000078296 00000 n 0000078460 00000 n 0000078616 00000 n 0000078776 00000 n 0000078932 00000 n 0000079106 00000 n 0000079244 00000 n 0000079362 00000 n 0000079400 00000 n 0000079508 00000 n trailer << /Size 137 /Root 135 0 R /Info 136 0 R /ID [ ] >> startxref 79908 %%EOF apvlv-0.1.1-Source/apvlv.1100644 1750 1750 11467 11521211167 14416 0ustar00pengdapengda.Dd December 24, 2009 .Dt apvlv 1 .Os .Sh NAME .Nm apvlv .Nd PDF/DJVU/UMD viewer with vim-like behaviour .Sh SYNOPSIS .Nm .Op options .Op file .Sh DESCRIPTION apvlv is a PDF/DJVU/UMD viewer, which behaves like vim. .Sh OPTIONS .Bl -tag -width "v" .It Fl c Ar file Load configuration from .Ar file instead of the default .Pa ~/.apvlvrc .It Fl h Show help message and exit .It Fl v Show version and exit .El .Sh COMMANDS The following command keys can be used inside apvlv. Some of them may be prefixed by a number (as in pressing "13G"), this is indicated by a .Ar count in their description. Unless noted otherwise, the default value for the number is 1. .Bl -tag -width "indent" .It o Display file chooser to open a PDF/DJVU/UMD file .It O Select a directory to display .It R Reload the current file .It r Rotate the document clockwise by 90 degrees .It G Show page number .Ar count .It gt Show next tab .It gT Show previous tab .It PageDown, C-f Go forward .Ar count pages .It PageUp, C-b Go backward .Ar count pages .It C-d Go forward .Ar count half pages .It C-u Go backward .Ar count half pages .It H Scroll to page head .It M Scroll to page middle .It L Scroll to page bottom .It s skip some pages .Ar count .It C-p, Up, k Scroll up .Ar count units .It C-n, Down, h Scroll down .Ar count units .It Backspace, Left, h Scroll left .Ar count units .It Space, Right, l Scroll right .Ar count units .It / Ar string Search forwards for .Ar string .It ? Ar string Search backwards for .Ar string .It f Toggle between fullscreen and window mode .It zi Zoom in .It zo Zoom out .It zw Zoom to fit window width .It zh Zoom to fit window height .It m Ar char Mark the current position to .Ar char , so that it can be recalled by pressing .Ar char .It ' Ar char Return to the mark position .Ar char .It '' Return to the last position .It q Close the current window .It v Select a area .It C-v Select a rectange area .It y copy the select area text to clipboard .El .Sh SETTINGS These can be set in ~/.apvlvrc with .Qq set Ar setting Op = Ar value . .Bl -tag -width "indent" .It fullscreen = yes/no Enable/Disable fullscreen .It width = Ar int Default window width .It height = Ar int Default window height .It defaultdir = Ar path Default directory for the open dialogue .It zoom = Ar mode Set default zoom level .Bl -tag -width "indent" .It normal The application sets the default zoom value .It fitwidth Fit pages to window width .It fitheight Fit pages to window height .It Ar float 1.0 for 100%, 2.0 for 200%, etc. .El .It content = yes/no Show content view first .It continuous = yes/no Show PDF/DJVU/UMD pages continuously or not. .It continuouspad = Ar int Padding betwen pages for continuous = yes .It autoscrollpage = yes/no Enable/Disable scrolling the pages when hitting a page tail/head .It noinfo = yes/no Disable/Enable the usage of ~/.apvlvinfo .It pdfcache = Ar int Set pdf cache size .It [no]cache Disable/Enable cache .It scrollbar = yes/no Set show scrollbar or not .It visualmode = yes/no Set use visual mode to select and copy text or not .It wrapscan = yes/no Set wrapscan to search text or not .It doubleclick = Ar action Set default double click action .Bl -tag -width "indent" .It none Selection nothing .It word Selection a word under the curcor to clipboard .It line Selection a line under the curcor to clipboard .It page Selection a page under the curcor to clipboard .El .It guioptions = m/T/mT Weather display menu, toolbar or mean and toolbar. .It autoreload = Ar int If auto reload document after some seconds .El .It inverted = yes/no If use inverted mode for pdf page .El .Sh PROMPT Like the COMMANDS, but prefixed with a colon: .Bl -tag -width "indent" .It :h[elp] Display the help document .It :h[elp] info Display the help document (section "introduction") .It :h[elp] command Display the help document (section "command") .It :h[elp] setting Display the help document (section "setting") .It :h[elp] prompt Display the help document (section "prompt") .It :q[uit] Close the current window .It :o[pen] Ar file Open .Ar file .It :doc Ar file Load .Ar file into the current window .It :TOtext Op Ar file Translate .Ar file (or the current page) to a text file .It :pr[int] Print the current document .It :tabnew Create a new tab .It :sp Horizontally split the current window .It :vsp Vertically split the current window .It :fp, :forwardpage Op Ar int Go forward .Ar int pages (1 by default) .It :bp, :prewardpage Op Ar int Go backward .Ar int pages (1 by default) .It :g, :goto Ar int Go to page .Ar int .It :z[oom] Ar mode Set zoom to .Ar mode (see "set zoom" in SETTINGS) .It : Ns Ar int Go to page .Ar int .El .Sh AUTHORS apvlv was written by Alf . .Pp This manual page was originally written by Stefan Ritter for the Debian project (but may be used by others), and was rewritten more beautifully by Daniel Friesel . apvlv-0.1.1-Source/CMakeLists.txt100644 1750 1750 12443 11521211167 15737 0ustar00pengdapengdaCMAKE_MINIMUM_REQUIRED (VERSION 2.6) PROJECT (apvlv) SET (PROJECT_MAJOR "0") SET (PROJECT_MINOR "1") SET (PROJECT_PATCH "1") SET (PACKAGE_VERSION "${PROJECT_MAJOR}.${PROJECT_MINOR}.${PROJECT_PATCH}") IF (WIN32) ADD_DEFINITIONS (-DDOCDIR=".") ELSE (WIN32) SET (SYSCONFDIR "/etc" CACHE PATH "Directory for system configuration of apvlv [/etc]" ) ADD_DEFINITIONS (-DSYSCONFDIR="${SYSCONFDIR}") SET (DOCDIR "${CMAKE_INSTALL_PREFIX}/share/doc/apvlv" CACHE PATH "Directory for documentations of apvlv [PREFIX/share/doc/apvlv]" ) ADD_DEFINITIONS (-DDOCDIR="${DOCDIR}") SET (MANDIR "${CMAKE_INSTALL_PREFIX}/share/man" CACHE PATH "Directory for man page of apvlv [PREFIX/share/man]" ) ENDIF (WIN32) ADD_DEFINITIONS (-DPACKAGE_NAME="apvlv" -DPACKAGE_VERSION="${PACKAGE_VERSION}" -DPACKAGE_BUGREPORT="Alf " -DRELEASE="rel" ) FIND_PACKAGE (PkgConfig) PKG_CHECK_MODULES (FREETYPE2 freetype2 REQUIRED) PKG_CHECK_MODULES (GTK2 gtk+-2.0 REQUIRED) PKG_CHECK_MODULES (GLIB2 glib-2.0 REQUIRED) PKG_CHECK_MODULES (GTHREAD2 gthread-2.0 REQUIRED) INCLUDE_DIRECTORIES (${FREETYPE2_INCLUDE_DIRS} ${GTK2_INCLUDE_DIRS} ${GLIB2_INCLUDE_DIRS} ${GTHREAD2_INCLUDE_DIRS}) LINK_DIRECTORIES (${FREETYPE2_LIBRARY_DIRS} ${GTK2_LIBRARY_DIRS} ${GLIB2_LIBRARY_DIRS} ${GTHREAD2_LIBRARY_DIRS}) IF (WIN32) SET (POPPLER_DIR ${CMAKE_HOME_DIRECTORY}/win32/poppler-src) INCLUDE_DIRECTORIES (${POPPLER_DIR}) LINK_DIRECTORIES (${CMAKE_BINARY_DIR}/poppler-build) SET (APVLV_REQ_LIBRARIES poppler.lib freetype.lib) ADD_SUBDIRECTORY (${POPPLER_DIR} ${CMAKE_BINARY_DIR}/poppler-build) ELSE (WIN32) PKG_CHECK_MODULES (POPPLER poppler-glib REQUIRED) INCLUDE_DIRECTORIES (${POPPLER_INCLUDE_DIRS}) LINK_DIRECTORIES (${POPPLER_LIBRARY_DIRS}) SET (APVLV_REQ_LIBRARIES ${POPPLER_LIBRARIES}) ENDIF (WIN32) OPTION (APVLV_WITH_DJVU "If build apvlv with djvu format support." ON) IF (APVLV_WITH_DJVU) ADD_DEFINITIONS (-DHAVE_LIBDJVU) IF (WIN32) SET (DJVULIBRE_DIR ${CMAKE_HOME_DIRECTORY}/win32/djvulibre) INCLUDE_DIRECTORIES (${DJVULIBRE_DIR}/include) LINK_DIRECTORIES (${DJVULIBRE_DIR}) SET (APVLV_REQ_LIBRARIES libdjvulibre.lib ${APVLV_REQ_LIBRARIES}) ELSE (WIN32) SET (APVLV_REQ_LIBRARIES -ldjvulibre ${APVLV_REQ_LIBRARIES}) ENDIF (WIN32) ENDIF (APVLV_WITH_DJVU) OPTION (APVLV_WITH_UMD "If build binary with umd format support." ON) IF (APVLV_WITH_UMD) ADD_DEFINITIONS (-DHAVE_LIBUMD) IF (WIN32) SET (LIBUMD_DIR ${CMAKE_HOME_DIRECTORY}/win32/libumd-trunk) ADD_SUBDIRECTORY (${LIBUMD_DIR} ${CMAKE_BINARY_DIR}/libumd-build) INCLUDE_DIRECTORIES (${LIBUMD_DIR}) LINK_DIRECTORIES (${CMAKE_BINARY_DIR}/libumd-build) SET (APVLV_REQ_LIBRARIES umd.lib zdll.lib ${APVLV_REQ_LIBRARIES}) ELSE (WIN32) SET (APVLV_REQ_LIBRARIES -lumd ${APVLV_REQ_LIBRARIES}) ENDIF (WIN32) ENDIF (APVLV_WITH_UMD) ADD_SUBDIRECTORY (src) IF (WIN32) INSTALL (FILES apvlvrc.example DESTINATION "." RENAME _apvlvrc) INSTALL (FILES apvlvrc.example Startup.pdf DESTINATION ".") INSTALL (DIRECTORY icons DESTINATION "." PATTERN ".svn" EXCLUDE) INSTALL (DIRECTORY ${CMAKE_HOME_DIRECTORY}/win32/poppler-data DESTINATION "." PATTERN ".svn" EXCLUDE) ELSE (WIN32) INSTALL (FILES apvlvrc.example DESTINATION ${SYSCONFDIR} RENAME apvlvrc) INSTALL (FILES apvlvrc.example Startup.pdf Startup.tex DESTINATION ${DOCDIR}) INSTALL (DIRECTORY icons DESTINATION ${DOCDIR} PATTERN ".svn" EXCLUDE) INSTALL (FILES apvlv.1 DESTINATION ${MANDIR}/man1) ENDIF (WIN32) SET (CPACK_PACKAGE_VENDOR "Alf") SET (CPACK_PACKAGE_DESCRIPTION_SUMMARY "apvlv - Alf's PDF/DJVU/UMD Viewer like Vim") SET (CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_MAJOR}) SET (CPACK_PACKAGE_VERSION_MINOR ${PROJECT_MINOR}) SET (CPACK_PACKAGE_VERSION_PATCH ${PROJECT_PATCH}) IF (UNIX) SET (CPACK_SET_DESTDIR ON) SET (CPACK_PACKAGE_CONTACT "Alf ") SET (CPACK_GENERATOR RPM DEB) SET (CPACK_RPM_PACKAGE_REQUIRES "gtk2 >= 2.10.4") SET (CPACK_DEBIAN_PACKAGE_DEPENDS "libpoppler-glib3 (>= 0.8.7-4), poppler-data (>= 0.2.0-2)") SET (CPACK_SOURCE_GENERATOR TGZ) SET (CPACK_SOURCE_IGNORE_FILES ${CMAKE_BINARY_DIR} ".svn" "win32" ) ELSE (UNIX) SET (CPACK_GENERATOR NSIS) SET (CPACK_NSIS_CONTACT "Alf ") SET (CPACK_NSIS_EXTRA_INSTALL_COMMANDS "CreateShortCut '\$DESKTOP\\\\apvlv.lnk' '\$INSTDIR\\\\apvlv.exe'") SET (CPACK_NSIS_EXTRA_UNINSTALL_COMMANDS "Delete '\$DESKTOP\\\\gsftc.lnk'") ENDIF (UNIX) INCLUDE(CPack)