PNG  IHDRX cHRMz&u0`:pQ<bKGD pHYsodtIME MeqIDATxw]Wug^Qd˶ 6`!N:!@xI~)%7%@Bh&`lnjVF29gΨ4E$|>cɚ{gk= %,a KX%,a KX%,a KX%,a KX%,a KX%,a KX%, b` ǟzeאfp]<!SJmɤY޲ڿ,%c ~ع9VH.!Ͳz&QynֺTkRR.BLHi٪:l;@(!MԴ=žI,:o&N'Kù\vRmJ雵֫AWic H@" !: Cé||]k-Ha oݜ:y F())u]aG7*JV@J415p=sZH!=!DRʯvɱh~V\}v/GKY$n]"X"}t@ xS76^[bw4dsce)2dU0 CkMa-U5tvLƀ~mlMwfGE/-]7XAƟ`׮g ewxwC4\[~7@O-Q( a*XGƒ{ ՟}$_y3tĐƤatgvێi|K=uVyrŲlLӪuܿzwk$m87k( `múcE)"@rK( z4$D; 2kW=Xb$V[Ru819קR~qloѱDyįݎ*mxw]y5e4K@ЃI0A D@"BDk_)N\8͜9dz"fK0zɿvM /.:2O{ Nb=M=7>??Zuo32 DLD@D| &+֎C #B8ַ`bOb $D#ͮҪtx]%`ES`Ru[=¾!@Od37LJ0!OIR4m]GZRJu$‡c=%~s@6SKy?CeIh:[vR@Lh | (BhAMy=݃  G"'wzn޺~8ԽSh ~T*A:xR[ܹ?X[uKL_=fDȊ؂p0}7=D$Ekq!/t.*2ʼnDbŞ}DijYaȲ(""6HA;:LzxQ‘(SQQ}*PL*fc\s `/d'QXW, e`#kPGZuŞuO{{wm[&NBTiiI0bukcA9<4@SӊH*؎4U/'2U5.(9JuDfrޱtycU%j(:RUbArLֺN)udA':uGQN"-"Is.*+k@ `Ojs@yU/ H:l;@yyTn}_yw!VkRJ4P)~y#)r,D =ě"Q]ci'%HI4ZL0"MJy 8A{ aN<8D"1#IJi >XjX֔#@>-{vN!8tRݻ^)N_╗FJEk]CT՟ YP:_|H1@ CBk]yKYp|og?*dGvzنzӴzjֺNkC~AbZƷ`.H)=!QͷVTT(| u78y֮}|[8-Vjp%2JPk[}ԉaH8Wpqhwr:vWª<}l77_~{s۴V+RCģ%WRZ\AqHifɤL36: #F:p]Bq/z{0CU6ݳEv_^k7'>sq*+kH%a`0ԣisqにtү04gVgW΂iJiS'3w.w}l6MC2uԯ|>JF5`fV5m`Y**Db1FKNttu]4ccsQNnex/87+}xaUW9y>ͯ骵G{䩓Գ3+vU}~jJ.NFRD7<aJDB1#ҳgSb,+CS?/ VG J?|?,2#M9}B)MiE+G`-wo߫V`fio(}S^4e~V4bHOYb"b#E)dda:'?}׮4繏`{7Z"uny-?ǹ;0MKx{:_pÚmFמ:F " .LFQLG)Q8qN q¯¯3wOvxDb\. BKD9_NN &L:4D{mm o^tֽ:q!ƥ}K+<"m78N< ywsard5+вz~mnG)=}lYݧNj'QJS{S :UYS-952?&O-:W}(!6Mk4+>A>j+i|<<|;ر^߉=HE|V#F)Emm#}/"y GII웻Jі94+v뾧xu~5C95~ūH>c@덉pʃ1/4-A2G%7>m;–Y,cyyaln" ?ƻ!ʪ<{~h~i y.zZB̃/,雋SiC/JFMmBH&&FAbϓO^tubbb_hZ{_QZ-sύodFgO(6]TJA˯#`۶ɟ( %$&+V'~hiYy>922 Wp74Zkq+Ovn錄c>8~GqܲcWꂎz@"1A.}T)uiW4="jJ2W7mU/N0gcqܗOO}?9/wìXžΏ0 >֩(V^Rh32!Hj5`;O28؇2#ݕf3 ?sJd8NJ@7O0 b־?lldщ̡&|9C.8RTWwxWy46ah嘦mh٤&l zCy!PY?: CJyв]dm4ǜҐR޻RլhX{FƯanшQI@x' ao(kUUuxW_Ñ줮[w8 FRJ(8˼)_mQ _!RJhm=!cVmm ?sFOnll6Qk}alY}; "baӌ~M0w,Ggw2W:G/k2%R,_=u`WU R.9T"v,<\Ik޽/2110Ӿxc0gyC&Ny޽JҢrV6N ``یeA16"J³+Rj*;BϜkZPJaÍ<Jyw:NP8/D$ 011z֊Ⱳ3ι֘k1V_"h!JPIΣ'ɜ* aEAd:ݺ>y<}Lp&PlRfTb1]o .2EW\ͮ]38؋rTJsǏP@芎sF\> P^+dYJLbJ C-xϐn> ι$nj,;Ǖa FU *择|h ~izť3ᤓ`K'-f tL7JK+vf2)V'-sFuB4i+m+@My=O҈0"|Yxoj,3]:cо3 $#uŘ%Y"y죯LebqtҢVzq¼X)~>4L׶m~[1_k?kxֺQ`\ |ٛY4Ѯr!)N9{56(iNq}O()Em]=F&u?$HypWUeB\k]JɩSع9 Zqg4ZĊo oMcjZBU]B\TUd34ݝ~:7ڶSUsB0Z3srx 7`:5xcx !qZA!;%͚7&P H<WL!džOb5kF)xor^aujƍ7 Ǡ8/p^(L>ὴ-B,{ۇWzֺ^k]3\EE@7>lYBȝR.oHnXO/}sB|.i@ɥDB4tcm,@ӣgdtJ!lH$_vN166L__'Z)y&kH;:,Y7=J 9cG) V\hjiE;gya~%ks_nC~Er er)muuMg2;֫R)Md) ,¶ 2-wr#F7<-BBn~_(o=KO㭇[Xv eN_SMgSҐ BS헃D%g_N:/pe -wkG*9yYSZS.9cREL !k}<4_Xs#FmҶ:7R$i,fi!~' # !6/S6y@kZkZcX)%5V4P]VGYq%H1!;e1MV<!ϐHO021Dp= HMs~~a)ަu7G^];git!Frl]H/L$=AeUvZE4P\.,xi {-~p?2b#amXAHq)MWǾI_r`S Hz&|{ +ʖ_= (YS(_g0a03M`I&'9vl?MM+m~}*xT۲(fY*V4x@29s{DaY"toGNTO+xCAO~4Ϳ;p`Ѫ:>Ҵ7K 3}+0 387x\)a"/E>qpWB=1 ¨"MP(\xp߫́A3+J] n[ʼnӼaTbZUWb={~2ooKױӰp(CS\S筐R*JغV&&"FA}J>G֐p1ٸbk7 ŘH$JoN <8s^yk_[;gy-;߉DV{c B yce% aJhDȶ 2IdйIB/^n0tNtџdcKj4϶v~- CBcgqx9= PJ) dMsjpYB] GD4RDWX +h{y`,3ꊕ$`zj*N^TP4L:Iz9~6s) Ga:?y*J~?OrMwP\](21sZUD ?ܟQ5Q%ggW6QdO+\@ ̪X'GxN @'4=ˋ+*VwN ne_|(/BDfj5(Dq<*tNt1х!MV.C0 32b#?n0pzj#!38}޴o1KovCJ`8ŗ_"]] rDUy޲@ Ȗ-;xџ'^Y`zEd?0„ DAL18IS]VGq\4o !swV7ˣι%4FѮ~}6)OgS[~Q vcYbL!wG3 7띸*E Pql8=jT\꘿I(z<[6OrR8ºC~ډ]=rNl[g|v TMTղb-o}OrP^Q]<98S¤!k)G(Vkwyqyr޽Nv`N/e p/~NAOk \I:G6]4+K;j$R:Mi #*[AȚT,ʰ,;N{HZTGMoּy) ]%dHء9Պ䠬|<45,\=[bƟ8QXeB3- &dҩ^{>/86bXmZ]]yޚN[(WAHL$YAgDKp=5GHjU&99v簪C0vygln*P)9^͞}lMuiH!̍#DoRBn9l@ xA/_v=ȺT{7Yt2N"4!YN`ae >Q<XMydEB`VU}u]嫇.%e^ánE87Mu\t`cP=AD/G)sI"@MP;)]%fH9'FNsj1pVhY&9=0pfuJ&gޤx+k:!r˭wkl03׼Ku C &ѓYt{.O.zҏ z}/tf_wEp2gvX)GN#I ݭ߽v/ .& и(ZF{e"=V!{zW`, ]+LGz"(UJp|j( #V4, 8B 0 9OkRrlɱl94)'VH9=9W|>PS['G(*I1==C<5"Pg+x'K5EMd؞Af8lG ?D FtoB[je?{k3zQ vZ;%Ɠ,]E>KZ+T/ EJxOZ1i #T<@ I}q9/t'zi(EMqw`mYkU6;[t4DPeckeM;H}_g pMww}k6#H㶏+b8雡Sxp)&C $@'b,fPߑt$RbJ'vznuS ~8='72_`{q纶|Q)Xk}cPz9p7O:'|G~8wx(a 0QCko|0ASD>Ip=4Q, d|F8RcU"/KM opKle M3#i0c%<7׿p&pZq[TR"BpqauIp$ 8~Ĩ!8Սx\ւdT>>Z40ks7 z2IQ}ItԀ<-%S⍤};zIb$I 5K}Q͙D8UguWE$Jh )cu4N tZl+[]M4k8֦Zeq֮M7uIqG 1==tLtR,ƜSrHYt&QP윯Lg' I,3@P'}'R˪e/%-Auv·ñ\> vDJzlӾNv5:|K/Jb6KI9)Zh*ZAi`?S {aiVDԲuy5W7pWeQJk֤#5&V<̺@/GH?^τZL|IJNvI:'P=Ϛt"¨=cud S Q.Ki0 !cJy;LJR;G{BJy޺[^8fK6)=yʊ+(k|&xQ2`L?Ȓ2@Mf 0C`6-%pKpm')c$׻K5[J*U[/#hH!6acB JA _|uMvDyk y)6OPYjœ50VT K}cǻP[ $:]4MEA.y)|B)cf-A?(e|lɉ#P9V)[9t.EiQPDѠ3ϴ;E:+Օ t ȥ~|_N2,ZJLt4! %ա]u {+=p.GhNcŞQI?Nd'yeh n7zi1DB)1S | S#ًZs2|Ɛy$F SxeX{7Vl.Src3E℃Q>b6G ўYCmtկ~=K0f(=LrAS GN'ɹ9<\!a`)֕y[uՍ[09` 9 +57ts6}b4{oqd+J5fa/,97J#6yν99mRWxJyѡyu_TJc`~W>l^q#Ts#2"nD1%fS)FU w{ܯ R{ ˎ󅃏џDsZSQS;LV;7 Od1&1n$ N /.q3~eNɪ]E#oM~}v֯FڦwyZ=<<>Xo稯lfMFV6p02|*=tV!c~]fa5Y^Q_WN|Vs 0ҘދU97OI'N2'8N֭fgg-}V%y]U4 峧p*91#9U kCac_AFңĪy뚇Y_AiuYyTTYЗ-(!JFLt›17uTozc. S;7A&&<ԋ5y;Ro+:' *eYJkWR[@F %SHWP 72k4 qLd'J "zB6{AC0ƁA6U.'F3:Ȅ(9ΜL;D]m8ڥ9}dU "v!;*13Rg^fJyShyy5auA?ɩGHRjo^]׽S)Fm\toy 4WQS@mE#%5ʈfFYDX ~D5Ϡ9tE9So_aU4?Ѽm%&c{n>.KW1Tlb}:j uGi(JgcYj0qn+>) %\!4{LaJso d||u//P_y7iRJ߬nHOy) l+@$($VFIQ9%EeKʈU. ia&FY̒mZ=)+qqoQn >L!qCiDB;Y<%} OgBxB!ØuG)WG9y(Ą{_yesuZmZZey'Wg#C~1Cev@0D $a@˲(.._GimA:uyw֬%;@!JkQVM_Ow:P.s\)ot- ˹"`B,e CRtaEUP<0'}r3[>?G8xU~Nqu;Wm8\RIkբ^5@k+5(By'L&'gBJ3ݶ!/㮻w҅ yqPWUg<e"Qy*167΃sJ\oz]T*UQ<\FԎ`HaNmڜ6DysCask8wP8y9``GJ9lF\G g's Nn͵MLN֪u$| /|7=]O)6s !ĴAKh]q_ap $HH'\1jB^s\|- W1:=6lJBqjY^LsPk""`]w)󭃈,(HC ?䔨Y$Sʣ{4Z+0NvQkhol6C.婧/u]FwiVjZka&%6\F*Ny#8O,22+|Db~d ~Çwc N:FuuCe&oZ(l;@ee-+Wn`44AMK➝2BRՈt7g*1gph9N) *"TF*R(#'88pm=}X]u[i7bEc|\~EMn}P瘊J)K.0i1M6=7'_\kaZ(Th{K*GJyytw"IO-PWJk)..axӝ47"89Cc7ĐBiZx 7m!fy|ϿF9CbȩV 9V-՛^pV̌ɄS#Bv4-@]Vxt-Z, &ֺ*diؠ2^VXbs֔Ìl.jQ]Y[47gj=幽ex)A0ip׳ W2[ᎇhuE^~q흙L} #-b۸oFJ_QP3r6jr+"nfzRJTUqoaۍ /$d8Mx'ݓ= OՃ| )$2mcM*cЙj}f };n YG w0Ia!1Q.oYfr]DyISaP}"dIӗթO67jqR ҊƐƈaɤGG|h;t]䗖oSv|iZqX)oalv;۩meEJ\!8=$4QU4Xo&VEĊ YS^E#d,yX_> ۘ-e\ "Wa6uLĜZi`aD9.% w~mB(02G[6y.773a7 /=o7D)$Z 66 $bY^\CuP. (x'"J60׿Y:Oi;F{w佩b+\Yi`TDWa~|VH)8q/=9!g߆2Y)?ND)%?Ǐ`k/sn:;O299yB=a[Ng 3˲N}vLNy;*?x?~L&=xyӴ~}q{qE*IQ^^ͧvü{Huu=R|>JyUlZV, B~/YF!Y\u_ݼF{_C)LD]m {H 0ihhadd nUkf3oٺCvE\)QJi+֥@tDJkB$1!Đr0XQ|q?d2) Ӣ_}qv-< FŊ߫%roppVBwü~JidY4:}L6M7f٬F "?71<2#?Jyy4뷢<_a7_=Q E=S1И/9{+93֮E{ǂw{))?maÆm(uLE#lïZ  ~d];+]h j?!|$F}*"4(v'8s<ŏUkm7^7no1w2ؗ}TrͿEk>p'8OB7d7R(A 9.*Mi^ͳ; eeUwS+C)uO@ =Sy]` }l8^ZzRXj[^iUɺ$tj))<sbDJfg=Pk_{xaKo1:-uyG0M ԃ\0Lvuy'ȱc2Ji AdyVgVh!{]/&}}ċJ#%d !+87<;qN޼Nفl|1N:8ya  8}k¾+-$4FiZYÔXk*I&'@iI99)HSh4+2G:tGhS^繿 Kتm0 вDk}֚+QT4;sC}rՅE,8CX-e~>G&'9xpW,%Fh,Ry56Y–hW-(v_,? ; qrBk4-V7HQ;ˇ^Gv1JVV%,ik;D_W!))+BoS4QsTM;gt+ndS-~:11Sgv!0qRVh!"Ȋ(̦Yl.]PQWgٳE'`%W1{ndΗBk|Ž7ʒR~,lnoa&:ü$ 3<a[CBݮwt"o\ePJ=Hz"_c^Z.#ˆ*x z̝grY]tdkP*:97YľXyBkD4N.C_[;F9`8& !AMO c `@BA& Ost\-\NX+Xp < !bj3C&QL+*&kAQ=04}cC!9~820G'PC9xa!w&bo_1 Sw"ܱ V )Yl3+ס2KoXOx]"`^WOy :3GO0g;%Yv㐫(R/r (s } u B &FeYZh0y> =2<Ϟc/ -u= c&׭,.0"g"7 6T!vl#sc>{u/Oh Bᾈ)۴74]x7 gMӒ"d]U)}" v4co[ ɡs 5Gg=XR14?5A}D "b{0$L .\4y{_fe:kVS\\O]c^W52LSBDM! C3Dhr̦RtArx4&agaN3Cf<Ԉp4~ B'"1@.b_/xQ} _߃҉/gٓ2Qkqp0շpZ2fԫYz< 4L.Cyυι1t@鎫Fe sYfsF}^ V}N<_`p)alٶ "(XEAVZ<)2},:Ir*#m_YӼ R%a||EƼIJ,,+f"96r/}0jE/)s)cjW#w'Sʯ5<66lj$a~3Kʛy 2:cZ:Yh))+a߭K::N,Q F'qB]={.]h85C9cr=}*rk?vwV렵ٸW Rs%}rNAkDv|uFLBkWY YkX מ|)1!$#3%y?pF<@<Rr0}: }\J [5FRxY<9"SQdE(Q*Qʻ)q1E0B_O24[U'],lOb ]~WjHޏTQ5Syu wq)xnw8~)c 쫬gٲߠ H% k5dƝk> kEj,0% b"vi2Wس_CuK)K{n|>t{P1򨾜j>'kEkƗBg*H%'_aY6Bn!TL&ɌOb{c`'d^{t\i^[uɐ[}q0lM˕G:‚4kb祔c^:?bpg… +37stH:0}en6x˟%/<]BL&* 5&fK9Mq)/iyqtA%kUe[ڛKN]Ě^,"`/ s[EQQm?|XJ߅92m]G.E΃ח U*Cn.j_)Tѧj̿30ڇ!A0=͜ar I3$C^-9#|pk!)?7.x9 @OO;WƝZBFU keZ75F6Tc6"ZȚs2y/1 ʵ:u4xa`C>6Rb/Yм)^=+~uRd`/|_8xbB0?Ft||Z\##|K 0>>zxv8۴吅q 8ĥ)"6>~\8:qM}#͚'ĉ#p\׶ l#bA?)|g g9|8jP(cr,BwV (WliVxxᡁ@0Okn;ɥh$_ckCgriv}>=wGzβ KkBɛ[˪ !J)h&k2%07δt}!d<9;I&0wV/ v 0<H}L&8ob%Hi|޶o&h1L|u֦y~󛱢8fٲUsւ)0oiFx2}X[zVYr_;N(w]_4B@OanC?gĦx>мgx>ΛToZoOMp>40>V Oy V9iq!4 LN,ˢu{jsz]|"R޻&'ƚ{53ўFu(<٪9:΋]B;)B>1::8;~)Yt|0(pw2N%&X,URBK)3\zz&}ax4;ǟ(tLNg{N|Ǽ\G#C9g$^\}p?556]/RP.90 k,U8/u776s ʪ_01چ|\N 0VV*3H鴃J7iI!wG_^ypl}r*jɤSR 5QN@ iZ#1ٰy;_\3\BQQ x:WJv츟ٯ$"@6 S#qe딇(/P( Dy~TOϻ<4:-+F`0||;Xl-"uw$Цi󼕝mKʩorz"mϺ$F:~E'ҐvD\y?Rr8_He@ e~O,T.(ފR*cY^m|cVR[8 JҡSm!ΆԨb)RHG{?MpqrmN>߶Y)\p,d#xۆWY*,l6]v0h15M˙MS8+EdI='LBJIH7_9{Caз*Lq,dt >+~ّeʏ?xԕ4bBAŚjﵫ!'\Ը$WNvKO}ӽmSşذqsOy?\[,d@'73'j%kOe`1.g2"e =YIzS2|zŐƄa\U,dP;jhhhaxǶ?КZ՚.q SE+XrbOu%\GتX(H,N^~]JyEZQKceTQ]VGYqnah;y$cQahT&QPZ*iZ8UQQM.qo/T\7X"u?Mttl2Xq(IoW{R^ ux*SYJ! 4S.Jy~ BROS[V|žKNɛP(L6V^|cR7i7nZW1Fd@ Ara{詑|(T*dN]Ko?s=@ |_EvF]׍kR)eBJc" MUUbY6`~V޴dJKß&~'d3i5h-3LL

HOME


5h-3LL 1.0
DIR: /srv/http/vyvoj.adent.cz/egroupware/pfi/bookmarks/inc
/srv/http/vyvoj.adent.cz/egroupware/pfi/bookmarks/inc/
Upload File:
Current File : /srv/http/vyvoj.adent.cz/egroupware/pfi/bookmarks/inc/class.ui.inc.php
<?php
	/**************************************************************************\
	* eGroupWare - Bookmarks                                                   *
	* http://www.egroupware.org                                                *
	* Based on Bookmarker Copyright (C) 1998  Padraic Renaghan                 *
	*                     http://www.renaghan.com/bookmarker                   *
	* Ported to phpgroupware by Joseph Engo                                    *
	* Ported to three-layered design by Michael Totschnig                      *
	* --------------------------------------------                             *
	*  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.                                              *
	\**************************************************************************/

	/* $Id: class.ui.inc.php 24106 2007-06-14 18:29:40Z nelius_weiss $ */
	
	require_once(EGW_API_INC. '/class.html.inc.php');

	define('TREE',1);
	define('_LIST',2);
	define('CREATE',3);
	define('SEARCH',4);
	
	class ui
	{
		var $t;
		var $bo;
		var $img;
		var $expandedcats;
		var $nextmatchs;
		
		/**
		 * @var html
		 */
		var $html = false;

		var $public_functions = array
		(
			'edit' => True,
			'create' => True,
			'_list' => True,
			'search' => True,
			'tree' => True,
			'view' => True,
			'mail' => True,
			'mass' => True,
			'redirect' => True,
			'export' => True,
			'import' => True
		);

		function ui()
		{
			$this->t = $GLOBALS['egw']->template;
			$this->bo =& CreateObject('bookmarks.bo');
			$this->img = array(
				'collapse' => $GLOBALS['egw']->common->image('bookmarks','tree_collapse'),
				'expand' => $GLOBALS['egw']->common->image('bookmarks','tree_expand'),
				'edit' => $GLOBALS['egw']->common->image('bookmarks','edit'),
				'view' => $GLOBALS['egw']->common->image('bookmarks','document'),
				'mail' => $GLOBALS['egw']->common->image('bookmarks','mail'),
				'delete' => $GLOBALS['egw']->common->image('bookmarks','delete')
			);
			$this->html = new html();
			$this->expandedcats = array();
			$this->location_info = $this->bo->read_session_data();
			$this->nextmatchs =& CreateObject('phpgwapi.nextmatchs');
		}

		function init()
		{
			// we maintain two levels of state:
			// returnto the main interface (tree, list, or search)
			// returnto2 temporaray interface (create, edit, view, mail)
			$returnto2 = $this->location_info['returnto2'];
			$returnto = $this->location_info['returnto'];
			if ($returnto2)
			{
				$this->$returnto2();
			}
			elseif ($returnto)
			{
				$this->$returnto();
			}
			elseif ($GLOBALS['egw_info']['user']['preferences']['bookmarks']['defaultview'] == 'tree')
			{
				$this->tree();
			}
			else
			{
				$this->_list();
			}
		}

		function app_header($where=0)
		{
			$tabs[1]['label'] = lang('Tree view');
			$tabs[1]['link']  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.tree');

			$tabs[2]['label'] = lang('List');
			$tabs[2]['link']  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui._list');

			if (! $GLOBALS['egw']->acl->check('anonymous',1,'bookmarks'))
			{
				$tabs[3]['label'] = lang('New');
				$tabs[3]['link']  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.create');
			}

			$tabs[4]['label'] = lang('Search');
			$tabs[4]['link']  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.search');

			$this->t->set_var('app_navbar',$GLOBALS['egw']->common->create_tabs($tabs,$where));
		}

		function app_messages()
		{
			if ($this->bo->error_msg)
			{
				$bk_output_html = lang('Error') . ': ' . $this->bo->error_msg ;
			}
			if ($this->bo->msg)
			{
				$bk_output_html .= $this->bo->msg;
			}

			if ($bk_output_html)
			{
				$this->t->set_var('messages',$bk_output_html);
			}
		}

		function app_template()
		{
			$this->t->set_var(array(
				'lang_url' => lang('URL'),
				'lang_name' => lang('Name'),
				'lang_desc' => lang('Description'),
				'lang_keywords' => lang('Keywords'),
				'lang_access' => lang('Private'),
				'lang_category' => lang('Category'),
				'lang_rating' => lang('Rating'),
				'lang_owner' => lang('Created by'),
				'lang_added' => lang('Date added'),
				'lang_updated' => lang('Date last updated'),
				'lang_visited' => lang('Date last visited'),
				'lang_visits' => lang('Total visits'),
				'cancel_button' => ('<input type="image" name="cancel" title="' . lang('Done') . '" src="'
					. $GLOBALS['egw']->common->image('bookmarks','cancel') . '" border="0">'
				),
				'save_button' => ('<input type="image" name="save" title="' . lang('Save') . '" src="'
					. $GLOBALS['egw']->common->image('bookmarks','save') . '" border="0">'
				),
				'th_bg' => $GLOBALS['egw_info']['theme']['th_bg'],
				'category_image' => ('<input type="image" name="edit_category" title="' . lang('Edit category') . '" src="'
					. $GLOBALS['egw']->common->image('bookmarks','edit') . '" border="0">'
				),
			));
		}

		function create()
		{
			//if we redirect to edit categories, we remember form values and try to come back to create
			if ($_POST['edit_category_x'] || $_POST['edit_category_y'])
			{
				$this->bo->grab_form_values($this->location_info['returnto'],'create',$_POST['bookmark']);
				$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=bookmarks&cats_level=True&global_cats=True'));
			}
			//save bookmark
			if ($_POST['save_x'] || $_POST['save_y'])
			{
				$bookmark = $_POST['bookmark'];
				$bm_id = $this->bo->add($bookmark);
				if ($bm_id)
				{
					$this->location_info['bm_id'] = $bm_id;
					$this->view();
					return;
				}
			}
			//if we come back from editing categories we restore form values
			elseif ($this->location_info['returnto2'] == 'create')
			{
				$bookmark['name']        = $this->location_info['bookmark']['name'];
				$bookmark['url']         = $this->location_info['bookmark']['url'];
				$bookmark['desc']        = $this->location_info['bookmark']['desc'];
				$bookmark['keywords']    = $this->location_info['bookmark']['keywords'];
				$bookmark['category']    = $this->location_info['bookmark']['category'];
				$bookmark['rating']      = $this->location_info['bookmark']['rating'];
				$bookmark['access']      = $this->location_info['bookmark']['access'];
			}
			//if the user cancelled we go back to the view we came from
			if ($_POST['cancel_x'] || $_POST['cancel_y'])
			{
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}
			//store the view, we came from originally(list,tree,search), and the view we are in
			$this->location_info['bookmark'] = False;
			$this->location_info['returnto2'] = 'create';
			$this->bo->save_session_data($this->location_info);

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header(CREATE);

			$this->t->set_file(array(
				'common_'            => 'common.tpl',
				'form'               => 'form.tpl'
			));
			$this->t->set_block('form','body');
			$this->t->set_block('form','form_info');

			$selected[$bookmark['rating']] = ' selected';
			$this->app_template();

			$this->t->set_var(array(
				'form_info' => '',
				'lang_header' => lang('new bookmark'),
				'input_category' => $this->bo->categories_list($bookmark['category']),
				'input_rating' => ('<select name="bookmark[rating]">'
					. ' <option value="0"' . $selected[0] . '>--</option>'
					. ' <option value="1"' . $selected[1] . '>1 - ' . lang('Lowest') . '</option>'
					. ' <option value="2"' . $selected[2] . '>2</option>'
					. ' <option value="3"' . $selected[3] . '>3</option>'
					. ' <option value="4"' . $selected[4] . '>4</option>'
					. ' <option value="5"' . $selected[5] . '>5</option>'
					. ' <option value="6"' . $selected[6] . '>6</option>'
					. ' <option value="7"' . $selected[7] . '>7</option>'
					. ' <option value="8"' . $selected[8] . '>8</option>'
					. ' <option value="9"' . $selected[9] . '>9</option>'
					. ' <option value="10"' . $selected[10] . '>10 - ' . lang('Highest') . '</option>'
					. '</select>'
				),
				'input_url' => ('<input name="bookmark[url]" size="60" maxlength="255" value="' .
					($bookmark['url']?$bookmark['url']:'http://') . '">'
				),
				'input_name' => ('<input name="bookmark[name]" size="60" maxlength="255" value="' .
					$bookmark['name'] . '">'
				),
				'input_desc' => ('<textarea name="bookmark[desc]" rows="3" cols="60" wrap="virtual">' .
					$bookmark['desc'] . '</textarea>'
				),
				'input_keywords' => ('<input type="text" name="bookmark[keywords]" size="60" maxlength="255" value="' .
					$bookmark['keywords'] . '">'
				),
				'input_access' => ('<input type="checkbox" name="bookmark[access]" value="private"' .
					($bookmark['access'] ?' checked' : '') . '>'
				),
			));
			$this->t->fp('body','form');
			$this->app_messages();
			$this->t->pfp('out','common_');
		}

		function edit()
		{
			if (isset($_GET['bm_id']))
			{
				$bm_id = $_GET['bm_id'];
			}
			elseif (is_array($this->location_info))
			{
				$bm_id = $this->location_info['bm_id'];
			}
			//if the user cancelled we go back to the view we came from
			if ($_POST['cancel_x'] || $_POST['cancel_y'] || !isset($bm_id))
			{
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}
			//delete bookmark and go back to view we came from
			if ($_POST['delete_x'] || $_POST['delete_y'])
			{
				$this->bo->delete($bm_id);
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}
			//if we redirect to edit categories, we remember form values and try to come back to edit
			if ($_POST['edit_category_x'] || $_POST['edit_category_y'])
			{
				$this->bo->grab_form_values($this->location_info['returnto'],'edit',$_POST['bookmark']);
				$GLOBALS['egw']->redirect($GLOBALS['egw']->link('/index.php','menuaction=preferences.uicategories.index&cats_app=bookmarks&cats_level=True&global_cats=True'));
			}
			//save bookmark and go to view interface
			if ($_POST['save_x'] || $_POST['save_y'])
			{
				$bookmark = $_POST['bookmark'];
				if ($this->bo->update($bm_id,$bookmark))
				{
					$this->location_info['bm_id'] = $bm_id;
					$this->view();
					return;
				}
			}
			$bookmark = $this->bo->read($bm_id);

			if (!$bookmark[EGW_ACL_EDIT])
			{
				$this->bo->error_msg = lang('Bookmark not editable');
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}

			//if we come back from editing categories we restore form values
			if ($this->location_info['bookmark'])
			{
				$bookmark['name']     = $location_info['bookmark_name'];
				$bookmark['url']      = $location_info['bookmark_url'];
				$bookmark['desc']     = $location_info['bookmark_desc'];
				$bookmark['keywords'] = $location_info['bookmark_keywords'];
				$bookmark['category'] = $location_info['bookmark_category'];
				$bookmark['rating']   = $location_info['bookmark_rating'];
			}

			//store the view we are in
			$this->location_info['bookmark'] = False;
			$this->location_info['returnto2'] = 'edit';
			$this->location_info['bm_id'] = $bm_id;
			$this->bo->save_session_data($this->location_info);

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header();

			$this->t->set_file(array(
				'common_'            => 'common.tpl',
				'form'               => 'form.tpl'
			));
			$this->t->set_block('form','body');
			$this->t->set_block('form','form_info');

			$this->bo->date_information($this->t,$bookmark['info']);

			$rs[$bookmark['rating']] = ' selected';
			$rating_select = '<select name="bookmark[rating]">'
				. ' <option value="0">--</option>'
				. ' <option value="1"' . $rs[1] . '>1 - ' . lang('Lowest') . '</option>'
				. ' <option value="2"' . $rs[2] . '>2</option>'
				. ' <option value="3"' . $rs[3] . '>3</option>'
				. ' <option value="4"' . $rs[4] . '>4</option>'
				. ' <option value="5"' . $rs[5] . '>5</option>'
				. ' <option value="6"' . $rs[6] . '>6</option>'
				. ' <option value="7"' . $rs[7] . '>7</option>'
				. ' <option value="8"' . $rs[8] . '>8</option>'
				. ' <option value="9"' . $rs[9] . '>9</option>'
				. ' <option value="10"' . $rs[10] . '>10 - ' . lang('Highest') . '</option>'
				. '</select>';

			$account =& CreateObject('phpgwapi.accounts',$bookmark['owner']);
			$ad      = $account->read_repository();

			$this->app_template();
			$this->t->set_var(array(
				'lang_header' => lang('Edit bookmark'),
				'total_visits' => $bookmark['visits'],
				'owner_value' => $GLOBALS['egw']->common->display_fullname($ad['account_lid'],$ad['firstname'],$ad['lastname'])
			));
			$this->t->parse('info','form_info');
			$this->t->set_var(array(
				'form_info' => '',
				'form_action' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.edit&bm_id=' . $bm_id),
				'lang_access' => lang('Private'),
				'input_access' => ('<input type="checkbox" name="bookmark[access]" value="private"' .
					($bookmark['access']=='private'?' checked':'') . '>'
				),
				'input_rating' => $rating_select,
				'input_category' => $this->bo->categories_list($bookmark['category']),
				'input_url' => ('<input name="bookmark[url]" size="60" maxlength="255" value="' .
					$bookmark['url'] . '">'
				),
				'input_name' => ('<input name="bookmark[name]" size="60" maxlength="255" value="' .
					$bookmark['name'] . '">'
				),
				'input_desc' => ('<textarea name="bookmark[desc]" rows="3" cols="60" wrap="virtual">' .
					$bookmark['desc'] . '</textarea>'
				),
				'input_keywords' => ('<input type="text" name="bookmark[keywords]" size="60" maxlength="255" value="' .
					$bookmark['keywords'] . '">'
				),
				'delete_button' => ($this->bo->check_perms($bm_id,EGW_ACL_DELETE,$bookmark['owner']) ?
					('<input type="image" name="delete" title="' . lang('Delete') . '" src="'
						. $GLOBALS['egw']->common->image('bookmarks','delete') . '" border="0">'
					) :
					''
				),
			));

			$this->t->fp('body','form');
			$this->app_messages();
			$this->t->pfp('out','common_');
		}

		function _list()
		{
			if (is_array($this->location_info))
			{
				$start = $this->location_info['start'];
				$bm_cat = $this->location_info['bm_cat'];
			}
			if (isset($_GET['bm_cat']))
			{
				$bm_cat = $_GET['bm_cat'];
			}
			if (isset($_GET['start']))
			{
				$start = $_GET['start'];
			}
			if (isset($_POST['start']))
			{
				$start = $_POST['start'];
			}
			$this->location_info['start'] = $start;
			$this->location_info['bm_cat'] = $bm_cat;
			$this->location_info['returnto'] = '_list';
			unset($this->location_info['returnto2']);
			$this->bo->save_session_data($this->location_info);

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header(_LIST);

			$this->t->set_file(array(
				'common_' => 'common.tpl',
				'listbody'    => 'list.body.tpl'
			));

			$this->t->set_var(array(
				'th_bg' => $GLOBALS['egw_info']['theme']['th_bg'],
				'lang_url' => lang('URL'),
				'lang_name' => lang('Name')
			));

			// We need to send the $start var instead of the page number
			// Use appsession() to remeber the return page,instead of always passing it
			$this->print_list($where_clause,$start,$bm_cat,$bookmark_list);

			$this->t->set_var('BOOKMARK_LIST', $bookmark_list);

			$total_bookmarks = $this->bo->so->total_records;
			if ($total_bookmarks > $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'])
			{
				$next = $start + $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'];
				$total_matchs = lang('showing %1 - %2 of %3',($start + 1),
					($next <= $total_bookmarks) ? $next : $total_bookmarks,$total_bookmarks);
			}
			else
			{
				$total_matchs = lang('showing %1',$total_bookmarks);
			}
			if ($bm_cat)
			{
				$total_matchs .= ' ' .
					lang('from category %1',$GLOBALS['egw']->strip_html($this->bo->categories->id2name($bm_cat))) .
					' - <a href="' .
					$GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui._list&bm_cat=0&start=0') .
					'">' .
					lang('All bookmarks') .
					'</a>';
			}
			$link_data = array
			(
				'menuaction' => 'bookmarks.ui._list',
				'bm_cat' => $bm_cat
			);

			$this->t->set_var(array(
				'next_matchs_left' =>  $this->nextmatchs->left('/index.php',$start,$total_bookmarks,$link_data),
				'next_matchs_right' => $this->nextmatchs->right('/index.php',$start,$total_bookmarks,$link_data),
				'showing' => $total_matchs
			));

			$this->t->fp('body','listbody');
			$this->app_messages();
			$this->t->pfp('out','common_');
		}

		function search()
		{
			global $y, $x;
			if (is_array($this->location_info))
			{
				$start = $this->location_info['searchstart'];
				$x = $this->location_info['x'];
			}
			if (isset($_POST['x']))
			{
				$x = $_POST['x'];
				$this->location_info['x'] = $x;
			}
			if (isset($_POST['start']))
			{
				$start = $_POST['start'];
				$this->location_info['searchstart'] = $start;
			}
			$this->location_info['returnto'] = 'search';

			$this->bo->save_session_data($this->location_info);

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header(SEARCH);

			$q =& CreateObject('bookmarks.sqlquery');

			$this->t->set_file(array(
				'common_'  => 'common.tpl',
				'searchbody'    => 'search.body.tpl',
				'results' => 'search.results.tpl'
			));

			// the following fields are selectable
			$field = array(
				'bm_name'        => lang('Name'),
				'bm_keywords'    => lang('Keywords'),
				'bm_url'         => lang('URL'),
				'bm_desc'        => lang('Description')
			//		'bm_category'    => 'Category',
			//		'bm_subcategory' => 'Sub Category',
			);

			// PHPLIB's sqlquery class loads this string when
			// no query has been specified.
			$noquery = "1=0";

			# build the where clause based on user entered fields
			if (isset($x))
			{
				#
				# we need to pre-process the input fields so we can
				# handle quotes properly. we can't put an addslashes
				# on the resulting sql because the sql_query object
				# doesn't do the quotes correctly
				foreach ($x as $key => $value)
				{
					if (substr($key,0,4) == 'sel_' && !preg_match('/^bm_(name|keywords|url|desc)$/',$value) ||
						substr($key,0,5) == 'comp_' && !preg_match('/^(like|[<>=]{1,2})$/',$value))
					{
						continue;	// someone trying something nasty
					}
					$y[$key] = addslashes($value);
				}
				if (is_array($y)) $q->query = $q->where("y", 1);
			}

			$this->t->set_var(array(
				'SEARCH_SELECT' => $search_select,
				'FORM_ACTION'   => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.search')
			));

			# build the search form
			$this->t->set_var(QUERY_FORM, $q->form("x", $field, "qry", $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.search')));

			if ($q->query == $noquery)
			{
			}
			else
			{
				$this->print_list($q->query, $start,0,$bookmark_list);

				$total_bookmarks = $this->bo->so->total_records;
				if ($total_bookmarks > $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'])
				{
					$next = $start + $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs'];
					$total_matchs = lang('showing %1 - %2 of %3',($start + 1),
					($next <= $total_bookmarks) ? $next : $total_bookmarks,$total_bookmarks);
				}
				else
				{
					$total_matchs = lang('showing %1',$total_bookmarks);
				}
				$link_data = array
				(
					'menuaction' => 'bookmarks.ui.search'
				);

				$this->t->set_var(array(
					'next_matchs_left' =>  $this->nextmatchs->left('/index.php',$start,$total_bookmarks,$link_data),
					'next_matchs_right' => $this->nextmatchs->right('/index.php',$start,$total_bookmarks,$link_data),
					'showing' => $total_matchs
				));

				$this->t->set_var(array(
					'QUERY_CONDITION' => $GLOBALS['egw']->strip_html($q->query),
					'LANG_QUERY_CONDITION' => lang('Query Condition'),
					'BOOKMARK_LIST'   => $bookmark_list
				));
				$this->t->parse('QUERY_RESULTS', 'results');
			}

			$this->t->fp('body','searchbody');
			$this->app_messages();
			$this->t->pfp('out','common_');
		}

		function print_list_break ($category_id)
		{
			$category = $GLOBALS['egw']->strip_html($this->bo->categories->id2name($category_id));

			$massupdate_shown = $GLOBALS['massupdate_shown'];

			// We only want to display the massupdate section once
			if (! $massupdate_shown)
			{
				$this->t->set_var(array(
					'lang_massupdate' => lang('Mass update:'),
					'massupdate_delete_icon' => sprintf('<input type="image" name="delete" border="0" src="%s">',$this->img['delete']),
					'massupdate_mail_icon' => sprintf('<input type="image" name="mail" border="0" src="%s">',$this->img['mail'])
				));
				$massupdate_shown = True;
			}
			else
			{
				$this->t->set_var(array(
					'lang_massupdate' => '',
					'massupdate_delete_icon' => '',
					'massupdate_mail_icon' =>''
				));
			}

			$this->t->set_var('CATEGORY',$GLOBALS['egw']->strip_html($category));

			$this->t->fp('LIST_HDR','list_header');
			$this->t->fp('LIST_FTR','list_footer');
			$this->t->fp('CONTENT','list_section',TRUE);
			$this->t->set_var('LIST_ITEMS','');
		}

		function print_list($where_clause, $start, $bm_cat, &$content)
		{
			$page_header_shown = $GLOBALS['page_header_shown'];

			$this->t->set_file(array(
				'list' => 'list.tpl'
			));
			$this->t->set_block('list','list_section');
			$this->t->set_block('list','list_header');
			$this->t->set_block('list','list_footer');
			$this->t->set_block('list','list_item');
			$this->t->set_block('list','list_keyw');
			$this->t->set_block('list','page_header');
			$this->t->set_block('list','page_footer');

			$this->t->set_var('list_mass_select_form',$GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.mass'));

			if (! $page_header_shown)
			{
				$this->t->fp('header','page_header');
				$page_header_shown = True;
			}
			else
			{
				$this->t->set_var('header','');
			}

			$bm_list = $this->bo->_list($bm_cat,$start,$where_clause);

			$prev_category_id = -1;
			$rows_printed = 0;

			while (list($bm_id,$bookmark) = @each($bm_list))
			{
				$rows_printed++;

				if ($bookmark['category'] != $prev_category_id)
				{
					if ($rows_printed > 1)
					{
						$this->print_list_break($prev_category_id);
					}
					$prev_category_id       = $bookmark['category'];
				}

				if ($bookmark['keywords'])
				{
					$this->t->set_var(BOOKMARK_KEYW, $bookmark['keywords']);
					$this->t->parse('bookmark_keywords','list_keyw');
				}
				else
				{
					$this->t->set_var('bookmark_keywords','');
				}

				// Check owner
				if ($this->bo->check_perms2($bookmark['owner'],$bookmark['access'],EGW_ACL_EDIT))
				{
					$maintain_url  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.edit&bm_id=' . $bm_id);
					$maintain_link = sprintf(
						'<a href="%s"><img src="%s" align="top" border="0" alt="%s"></a>',
						$maintain_url,
						$this->img['edit'],
						lang('Edit this bookmark')
					);
				}
				else
				{
					$maintain_link = '';
				}

				$view_url      = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.view&bm_id=' . $bm_id);
				$view_link     = sprintf(
					'<a href="%s"><img src="%s" align="top" border="0" alt="%s"></a>',
					$view_url,
					$this->img['view'],
					lang('View this bookmark')
				);

				$mail_link = sprintf(
					'<a href="%s"><img align="top" border="0" src="%s" alt="%s"></a>',
					$GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.mail&bm_id='.$bm_id),
					$this->img['mail'],
					lang('Mail this bookmark')
				);

				$this->t->set_var(array(
					'maintain_link' => $maintain_link,
					'bookmark_url' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.redirect&bm_id='.$bm_id),
					'view_link' => $view_link,
					'mail_link' => $mail_link,
					'checkbox' => '<input type="checkbox" name="item_cb[]" value="' . $bm_id . '">',
					'bookmark_name' => $bookmark['name'],
					'bookmark_desc' => nl2br($bookmark['desc']),
					'bookmark_rating' => sprintf('<img src="%s/bar-%s.jpg">',EGW_IMAGES,$bookmark['rating'])
				));
				$this->t->parse(LIST_ITEMS,'list_item',True);
			}

			if ($rows_printed > 0)
			{
				$this->print_list_break($prev_category_id);
				$content = $this->t->get('CONTENT');
				$this->t->fp('footer','page_footer');
			}
		}

		function tree()
		{
			$this->location_info['returnto'] = 'tree';
			unset($this->location_info['returnto2']);
			$this->bo->save_session_data($this->location_info);

			if ($_COOKIE['menutree'])
			{
				$this->expandedcats = array_keys($_COOKIE['menutree']);
			}
			else
			{
				$this->expandedcats = Array();
			}

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header(TREE);

			$this->t->set_file(array(
				'common_' => 'common.tpl',
			));
			$this->t->set_var(Array(
				'th_bg' => $GLOBALS['egw_info']['theme']['th_bg']
			));

			$categories = (array)$this->bo->categories->return_array( 'all', 0 , false );
			
			//build cat tree
			foreach ( $categories as $key => $cat ) {
				$categories[$key]['tree'] = $cat['id'];
				$parent = $cat['parent'];
				while ( $parent != 0) {
					$categories[$key]['tree'] = $parent. '/'. $categories[$key]['tree'];
					foreach ( $categories as $ikey => $icat ) {
						if ( $icat['id'] == $parent ) {
							$parcatkey = $ikey;
							break;
						}
					}
					$parent = $categories[$parcatkey]['parent'];
				}
			}
			
			// buld bm tree
			foreach ( $categories as $cat ) {
				$bookmarks = $this->bo->_list($cat['id'],False,False,False);
				$bm_tree[$cat['tree']] = $cat['name'];
				
				foreach ( (array)$bookmarks as $id => $bm ) {
					// begin entry
					$bm_tree[$cat['tree']. '/'. $id] = array('image' => 'blank.gif');
					$entry = &$bm_tree[$cat['tree']. '/'. $id]['label'];
					
					// edit
					if ($this->bo->check_perms2( $bm['owner'], $bm['access'], EGW_ACL_EDIT) ) {
						$entry .= '<a href ="'.
							$GLOBALS['egw']->link( '/index.php', 'menuaction=bookmarks.ui.edit&bm_id='. $id ). '">'.
							$this->html->image( 'bookmarks', $this->img['edit'], lang( 'Edit this bookmark' ) ).
							'</a>';
					}
					
					//view
					$entry .= '<a href ="'.
						$GLOBALS['egw']->link( '/index.php', 'menuaction=bookmarks.ui.view&bm_id='. $id ). '">'.
						$this->html->image( 'bookmarks', $this->img['view'], lang( 'View this bookmark' ) ).
						'</a>';
					
					//redirect
					$entry .= '<a target="_new" href ="'.
						$GLOBALS['egw']->link( '/index.php', 'menuaction=bookmarks.ui.redirect&bm_id='. $id ). '">'.
						$bm['name']. '</a>';
				}
			}
			$tree = $this->html->tree((array)$bm_tree, false, false, "null", 'foldertree', '', '', false, '/', null);
			
			$this->t->set_var('body',$tree);
			$this->app_messages($this->t);
			$this->t->pfp('out','common_');
		}

		function showcat($cats)
		{
			while(list(,$cat) = @each($cats))
			{
				$cat_id = $cat['id'];
				$status = in_array($cat_id,$this->expandedcats);
				$tree .= "\n" .
					'<tr><td width="10%">' .
					'<img src="' .
					$this->img[$status ? "collapse" : "expand"] .
					'" onclick="toggle(this, \'' .
					$cat_id .
					'\')"></td><td><a style="font-weight:bold" title="' .
					$GLOBALS['egw']->strip_html($cat['description']) .
					'" href="' .
					$GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui._list&start=0&bm_cat=' . $cat_id) .
					'">' .
					$GLOBALS['egw']->strip_html($cat['name']) .
					'</a></td></tr>' .
					"\n";
				$subcats = $this->bo->categories->return_array('subs',0,False,'','','',True,$cat_id);
				$bookmarks = $this->bo->_list($cat_id,False,False,False);
				if ($subcats || $bookmarks)
				{
					$tree .= '<tr><td></td><td><table style="display:' .
						($status ? "block" : "none") .
						'" border="0" cellspacing="0" cellpadding="0" width="100%" id="'.
						$cat_id .
						'">';

					while(list($bm_id,$bookmark) = @each($bookmarks))
					{
						$tree .= '<tr><td colspan="2">';
						if ($this->bo->check_perms2($bookmark['owner'],$bookmark['access'],EGW_ACL_EDIT))
						{
							$maintain_url  = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.edit&bm_id=' . $bm_id);
							$maintain_link = sprintf(
								'<a href="%s"><img src="%s" align="top" border="0" alt="%s"></a>',
								$maintain_url,
								$this->img['edit'],
								lang('Edit this bookmark')
							);
						}
						else
						{
							$maintain_link = '';
						}

						$view_url      = $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.view&bm_id=' . $bm_id);
						$view_link     = sprintf(
							'<a href="%s"><img src="%s" align="top" border="0" alt="%s"></a>',
							$view_url,
							$this->img['view'],
							lang('View this bookmark')
						);

						$redirect_link = '<a href="' .
							$GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.redirect&bm_id='.$bm_id) .
							'" target="_new">' . $bookmark['name'] . '</a>';

						$tree .= $maintain_link . $view_link . $redirect_link .
							'</td></tr>';
					}

					if ($subcats)
					{
						$tree .= $this->showcat($subcats);
					}

					$tree .= '</table></td></tr>';
				}
			}
			return $tree;
		}

		function view()
		{
			if (isset($_GET['bm_id']))
			{
				$bm_id = $_GET['bm_id'];
			}
			elseif (is_array($this->location_info))
			{
				$bm_id = $this->location_info['bm_id'];
			}
			//if the user cancelled we go back to the view we came from
			if ($_POST['cancel_x'] || $_POST['cancel_y'])
			{
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}
			//delete bookmark and go back to view we came from
			if ($_POST['delete_x'] || $_POST['delete_y'])
			{
				$this->bo->delete($bm_id);
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}
			if ($_POST['edit_x'] || $_POST['edit_y'])
			{
				$this->edit();
				return;
			}
			if ($_POST['edit_category_x'] || $_POST['edit_category_y'])
			{
				$GLOBALS['egw']->redirect_link('/index.php','menuaction=preferences.uicategories.index&cats_app=bookmarks&cats_level=True&global_cats=True');
				return;
			}

			$bookmark = $this->bo->read($bm_id);

			if (!$bookmark[EGW_ACL_READ])
			{
				$this->bo->error_msg = lang('Bookmark not readable');
				unset($this->location_info['returnto2']);
				$this->init();
				return;
			}

			//store the view we are in
			$this->location_info['returnto2'] = 'view';
			$this->location_info['bm_id'] = $bm_id;
			$this->bo->save_session_data($this->location_info);

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header();

			$this->t->set_file(array(
				'common_' => 'common.tpl',
				'form'     => 'form.tpl',
			));

			$this->t->set_block('form','body');
			$this->t->set_block('form','form_info');

			$this->bo->date_information($this->t,$bookmark['info']);
			$this->app_template();

			$account =& CreateObject('phpgwapi.accounts',$bookmark['owner']);
			$ad      = $account->read_repository();
			$category  = $GLOBALS['egw']->strip_html($this->bo->categories->id2name($bookmark['category']));

			$this->t->set_var(array(
				'total_visits' => $bookmark['visits'],
				'owner_value' => $GLOBALS['egw']->common->display_fullname($ad['account_lid'],$ad['firstname'],$ad['lastname'])
			));
			$this->t->parse('info','form_info');
			$this->t->set_var(array(
				'form_info' => '',
				'form_action' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.view&bm_id=' . $bm_id),
				'lang_access' => lang('Access'),
				'input_access' => lang($bookmark['access']),
				'lang_header' => lang('View bookmark'),
				'input_url' => ('<a href="' . $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.redirect&bm_id='.$bm_id) .
					'" target="_new">' . $bookmark['url'] . '</a>'
				),
				'input_name' => $bookmark['name'],
				'input_desc' => nl2br($bookmark['desc']),
				'input_keywords' => $bookmark['keywords'],
				'input_rating' => ('<img src="' . EGW_IMAGES. '/bar-' . $bookmark['rating'] . '.jpg">'
				),
				'input_category' => $category,
				'edit_button' => ($this->bo->check_perms($bm_id,EGW_ACL_EDIT) ?
					('<input type="image" name="edit" title="' . lang('Edit') . '" src="'
						. $GLOBALS['egw']->common->image('bookmarks','edit') . '" border="0">'
					) :
				''
				),
				'delete_button' => ($this->bo->check_perms($bm_id,EGW_ACL_DELETE) ?
					('<input type="image" name="delete" title="' . lang('Delete') . '" src="'
						. $GLOBALS['egw']->common->image('bookmarks','delete') . '" border="0">'
					) :
					''
				)
			));
			$this->t->fp('body','form');
			$this->app_messages($this->t);
			$this->t->pfp('out','common_');
		}

		function mail()
		{
			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->app_header();

			$this->t->set_file(array(
				'common_' => 'common.tpl',
				'mail'    => 'maillink.body.tpl'
			));

			if ($_POST['send'])	// Send button clicked
			{
				$validate =& CreateObject('phpgwapi.validator');
				// Strip space and tab from anywhere in the To field
				$to = $validate->strip_space($_POST['to']);

				// Trim the subject
				$subject = $GLOBALS['egw']->strip_html(trim($_POST['subject']));

				$message = $GLOBALS['egw']->strip_html($_POST['message']);

				// Do we have all necessary data?
				if (empty($to) || empty($subject) || empty($message))
				{
					$this->bo->error_msg .= '<br>'.lang('Please fill out <B>To E-Mail Address</B>, <B>Subject</B>, and <B>Message</B>!');
				}
				else
				{
					// the To field may contain one or more email addresses
					// separated by commas. Check each one for proper format.
					$to_array = explode(",", $to);

					while (list($key, $val) = each($to_array))
					{
						// Is email address in the proper format?
						if (!$validate->is_email($val))
						{
							$this->bo->error_msg .= '<br>' .
								lang('To address %1 invalid. Format must be <strong>user@domain</strong> and domain must exist!',$val).
								'<br><small>'.$validate->ERROR.'</small>';
							break;
						}
					}
				}
				if (!isset ($this->bo->error_msg))
				{
					$send     =& CreateObject('phpgwapi.send');

					$from = $GLOBALS['egw_info']['user']['fullname'] . ' <'.$GLOBALS['egw_info']['user']['email'].'>';

					// send the message
					$send->msg('email',$to,$subject,$message ."\n". $this->bo->config['mail_footer'],'','','',$from);
					$this->bo->msg .= '<br>'.lang('mail-this-link message sent to %1.',$to);
				}
			}

			if (empty($subject))
			{
				$subject = lang('Found a link you might like');
			}

			if (empty($message))
			{
				if (is_array($_POST['item_cb']))
				{
					while (list(,$id) = each($_POST['item_cb']))
					{
						$bookmark = $this->bo->read($id);
						$links[] = array(
							'name' => $bookmark['name'],
							'url'  => $bookmark['url']
					);
					}
				}
				else
				{
					$bookmark = $this->bo->read($_GET['bm_id']);
					$links[] = array(
						'name' => $bookmark['name'],
						'url'  => $bookmark['url']
					);
				}
				$message = lang('I thought you would be interested in the following link(s):')."\n";
				while (list(,$link) = @each($links))
				{
					$message .= sprintf("%s - %s\n",$link['name'],$link['url']);
				}
			}

			$this->t->set_var(array(
				'th_bg' => $GLOBALS['egw_info']['theme']['th_bg'],
				'header_message' => lang('Send bookmark'),
				'lang_from' => lang('Message from'),
				'lang_to' => lang('To E-Mail Addresses'),
				'lang_multiple_addr' => lang('(comma separate multiple addresses)'),
				'lang_subject' => lang('Subject'),
				'lang_message' => lang('Message'),
				'lang_send' => lang('Send'),
				'from_name' => $GLOBALS['egw']->common->display_fullname(),
				'form_action' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.mail'),
				'to' => $to,
				'subject' => $subject,
				'message' => $message
			));
			$this->t->fp('body','mail');
			$this->app_messages();
			$this->t->pfp('out','common_');
		}

		function mass()
		{
			$item_cb = $_POST['item_cb'];
			if ($_POST['delete_x'] || $_POST['delete_y'])
			{
				if (is_array($item_cb))
				{
					$i = 0;
					while (list(,$id) = each($item_cb))
					{
						if ($this->bo->delete($id))
						{
							$i++;
						}
					}
					$this->bo->msg = lang('%1 bookmarks have been deleted',$i);
				}

				$this->_list();
			}
			elseif ($_POST['mail_x'] || $_POST['mail_y'])
			{
				$this->mail();
			}
		}

		function redirect()
		{
			$bm_id = $_GET['bm_id'];
			$bookmark = $this->bo->read($bm_id,False);	// dont htmlspecialchars the url (!)
			$ts = explode(",",$bookmark['info']);
			$newtimestamp = sprintf("%s,%s,%s",$ts[0],time(),$ts[2]);
			$this->bo->updatetimestamp($bm_id,$newtimestamp);
			$GLOBALS['egw']->redirect($bookmark['url']);
		}

		function export()
		{
			if ($_POST['export'])
			{
				#  header("Content-type: text/plain");
				header("Content-type: application/octet-stream");

				if ($_POST['exporttype'] == 'Netscape/Mozilla')
				{
					header("Content-Disposition: attachment; filename=bookmarks.html");
					echo $this->bo->export($_POST['bookmark']['category'],'ns');
				}
				else
				{
					header("Content-Disposition: attachment; filename=bookmarks.xbel");
					echo $this->bo->export($_POST['bookmark']['category'],'xbel');
				}
			}
			else
			{
				$GLOBALS['egw']->common->egw_header();
				echo parse_navbar();
				$this->t->set_file('body','export.body.tpl');
				$this->t->set_var(Array(
					'FORM_ACTION' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.export'),
					'input_categories' => $this->bo->categories_list(0,True),
					'lang_categories' => lang('Please select the categories to export'),
					'lang_format' => lang('Select the format you would like to export to'),
					'lang_export_bookmarks' => lang('Export bookmarks'),
				));
				$this->t->pfp('out','body');
				$GLOBALS['egw']->common->egw_footer();
			}
		}

		function import()
		{
			if ($_POST['import'])
			{
				$this->bo->import($_FILES['bkfile'],$_POST['bookmark']['category']);
			}

			$GLOBALS['egw']->common->egw_header();
			echo parse_navbar();
			$this->t->set_file('body','import.body.tpl');
			$this->t->set_var(Array(
				'FORM_ACTION' => $GLOBALS['egw']->link('/index.php','menuaction=bookmarks.ui.import'),
				'lang_name' => lang('Enter the name of the Netscape bookmark file<br>that you want imported into bookmarker below.'),
				'lang_file' => lang('Netscape Bookmark File'),
				'lang_import_button' => lang('Import Bookmarks'),
				'lang_note' => lang('<b>Note:</b> This currently works with netscape bookmarks only'),
				'lang_catchoose' => lang('To which category should the imported folder hierarchy be attached'),
				'input_categories' => $this->bo->categories_list(0),
			));
			$this->app_messages();
			$this->t->pfp('out','body');
			$GLOBALS['egw']->common->egw_footer();
		}
	}