[wysiwyg editor] disable server browsing by default
# copyright 2003-2011 LOGILAB S.A. (Paris, FRANCE), all rights reserved.# contact http://www.logilab.fr/ -- mailto:contact@logilab.fr## This file is part of CubicWeb.## CubicWeb is free software: you can redistribute it and/or modify it under the# terms of the GNU Lesser General Public License as published by the Free# Software Foundation, either version 2.1 of the License, or (at your option)# any later version.## CubicWeb 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 Lesser General Public License for more# details.## You should have received a copy of the GNU Lesser General Public License along# with CubicWeb. If not, see <http://www.gnu.org/licenses/>."""Set of tree views / tree-building widgets, some based on jQuery treeviewplugin."""__docformat__="restructuredtext en"_=unicodefromwarningsimportwarnfromlogilab.mtconverterimportxml_escapefromcubicweb.utilsimportmake_uid,jsonfromcubicweb.selectorsimportadaptablefromcubicweb.viewimportEntityViewfromcubicweb.mixinsimport_done_initfromcubicweb.web.viewsimportbaseviewsdeftreecookiename(treeid):returnstr('%s-treestate'%treeid)classBaseTreeView(baseviews.ListView):"""base tree view"""__regid__='tree'__select__=adaptable('ITree')item_vid='treeitem'defcall(self,done=None,**kwargs):ifdoneisNone:done=set()super(BaseTreeView,self).call(done=done,**kwargs)defcell_call(self,row,col=0,vid=None,done=None,maxlevel=None,**kwargs):assertmaxlevelisNoneormaxlevel>0done,entity=_done_init(done,self,row,col)ifdoneisNone:# entity is actually an error messageself.w(u'<li class="badcontent">%s</li>'%entity)returnself.open_item(entity)entity.view(vidorself.item_vid,w=self.w,**kwargs)ifmaxlevelisnotNone:maxlevel-=1ifmaxlevel==0:self.close_item(entity)returnrelatedrset=entity.cw_adapt_to('ITree').children(entities=False)self.wview(self.__regid__,relatedrset,'null',done=done,maxlevel=maxlevel,**kwargs)self.close_item(entity)defopen_item(self,entity):self.w(u'<li class="%s">\n'%entity.__regid__.lower())defclose_item(self,entity):self.w(u'</li>\n')classTreePathView(EntityView):"""a recursive path view"""__regid__='path'__select__=adaptable('ITree')item_vid='oneline'separator=u' > 'defcall(self,**kwargs):self.w(u'<div class="pathbar">')super(TreePathView,self).call(**kwargs)self.w(u'</div>')defcell_call(self,row,col=0,vid=None,done=None,**kwargs):done,entity=_done_init(done,self,row,col)ifdoneisNone:# entity is actually an error messageself.w(u'<span class="badcontent">%s</span>'%entity)returnparent=entity.cw_adapt_to('ITree').parent()ifparent:parent.view(self.__regid__,w=self.w,done=done)self.w(self.separator)entity.view(vidorself.item_vid,w=self.w)classTreeComboBoxView(TreePathView):"""display folder in edition's combobox"""__regid__='combobox'item_vid='text'separator=u' > '# XXX rename regid to ajaxtree/foldabletree or something like that (same for# treeitemview)classTreeView(EntityView):"""ajax tree view, click to expand folder"""__regid__='treeview'itemvid='treeitemview'subvid='oneline'cssclass='treeview widget'title=_('tree view')def_init_params(self,subvid,treeid,initial_load,initial_thru_ajax,morekwargs):form=self._cw.formifsubvidisNone:subvid=form.pop('treesubvid',self.subvid)# consume itiftreeidisNone:treeid=form.pop('treeid',None)iftreeidisNone:treeid='throw_away'+make_uid('uid')if'morekwargs'inself._cw.form:ajaxargs=json.loads(form.pop('morekwargs'))# got unicode & python keywords must be stringsmorekwargs.update(dict((str(k),v)fork,vinajaxargs.iteritems()))toplevel_thru_ajax=form.pop('treeview_top',False)orinitial_thru_ajaxtoplevel=toplevel_thru_ajaxor(initial_loadandnotform.get('fname'))returnsubvid,treeid,toplevel_thru_ajax,topleveldef_init_headers(self,treeid,toplevel_thru_ajax):self._cw.add_css('jquery.treeview.css')self._cw.add_js(('cubicweb.ajax.js','cubicweb.widgets.js','jquery.treeview.js'))self._cw.html_headers.add_onload(u"""jQuery("#tree-%s").treeview({toggle: toggleTree, prerendered: true});"""%treeid)defcall(self,subvid=None,treeid=None,initial_load=True,initial_thru_ajax=False,**morekwargs):subvid,treeid,toplevel_thru_ajax,toplevel=self._init_params(subvid,treeid,initial_load,initial_thru_ajax,morekwargs)ulid=' 'iftoplevel:self._init_headers(treeid,toplevel_thru_ajax)ulid=' id="tree-%s"'%treeidself.w(u'<ul%s class="%s">'%(ulid,self.cssclass))# XXX force sorting on x.sortvalue() (which return dc_title by default)# we need proper ITree & co specification to avoid this.# (pb when type ambiguity at the other side of the tree relation,# unability to provide generic implementation on eg Folder...)fori,entityinenumerate(sorted(self.cw_rset.entities(),key=lambdax:x.sortvalue())):ifi+1<len(self.cw_rset):morekwargs['is_last']=Falseelse:morekwargs['is_last']=Trueentity.view(self.itemvid,vid=subvid,parentvid=self.__regid__,treeid=treeid,w=self.w,**morekwargs)self.w(u'</ul>')defcell_call(self,*args,**allargs):""" does not makes much sense until you have to invoke somentity.view('treeview') """allargs.pop('row')allargs.pop('col')self.call(*args,**allargs)classFileTreeView(TreeView):"""specific version of the treeview to display file trees """__regid__='filetree'cssclass='treeview widget filetree'title=_('file tree view')defcall(self,subvid=None,treeid=None,initial_load=True,**kwargs):super(FileTreeView,self).call(treeid=treeid,subvid='filetree-oneline',initial_load=initial_load,**kwargs)classFileItemInnerView(EntityView):"""inner view used by the TreeItemView instead of oneline view This view adds an enclosing <span> with some specific CSS classes around the oneline view. This is needed by the jquery treeview plugin. """__regid__='filetree-oneline'defcell_call(self,row,col):entity=self.cw_rset.get_entity(row,col)itree=entity.cw_adapt_to('ITree')ifitreeandnotitree.is_leaf():self.w(u'<div class="folder">%s</div>\n'%entity.view('oneline'))else:# XXX define specific CSS classes according to mime typesself.w(u'<div class="file">%s</div>\n'%entity.view('oneline'))classDefaultTreeViewItemView(EntityView):"""default treeitem view for entities which don't adapt to ITree"""__regid__='treeitemview'defcell_call(self,row,col,vid='oneline',treeid=None,**morekwargs):asserttreeidisnotNoneitemview=self._cw.view(vid,self.cw_rset,row=row,col=col)last_class=morekwargs['is_last']and' class="last"'or''self.w(u'<li%s>%s</li>'%(last_class,itemview))classTreeViewItemView(EntityView):"""specific treeitem view for entities which adapt to ITree (each item should be expandable if it's not a tree leaf) """__regid__='treeitemview'__select__=adaptable('ITree')default_branch_state_is_open=Falsedefopen_state(self,eeid,treeid):cookies=self._cw.get_cookie()treestate=cookies.get(treecookiename(treeid))iftreestate:returnstr(eeid)intreestate.value.split(':')returnself.default_branch_state_is_opendefcell_call(self,row,col,treeid,vid='oneline',parentvid='treeview',is_last=False,**morekwargs):w=self.wentity=self.cw_rset.get_entity(row,col)itree=entity.cw_adapt_to('ITree')liclasses=[]is_open=self.open_state(entity.eid,treeid)is_leaf=itreeisNoneoritree.is_leaf()ifis_leaf:ifis_last:liclasses.append('last')w(u'<li class="%s">'%u' '.join(liclasses))else:rql=itree.children_rql()%{'x':entity.eid}url=xml_escape(self._cw.build_url('json',rql=rql,vid=parentvid,pageid=self._cw.pageid,treeid=treeid,fname='view',treesubvid=vid,morekwargs=json.dumps(morekwargs)))divclasses=['hitarea']ifis_open:liclasses.append('collapsable')divclasses.append('collapsable-hitarea')else:liclasses.append('expandable')divclasses.append('expandable-hitarea')ifis_last:ifis_open:liclasses.append('lastCollapsable')divclasses.append('lastCollapsable-hitarea')else:liclasses.append('lastExpandable')divclasses.append('lastExpandable-hitarea')ifis_open:w(u'<li class="%s">'%u' '.join(liclasses))else:w(u'<li cubicweb:loadurl="%s" class="%s">'%(url,u' '.join(liclasses)))iftreeid.startswith('throw_away'):divtail=''else:divtail=""" onclick="asyncRemoteExec('node_clicked', '%s', '%s')" """%(treeid,entity.eid)w(u'<div class="%s"%s></div>'%(u' '.join(divclasses),divtail))# add empty <ul> because jquery's treeview plugin checks for# sublists presenceifnotis_open:w(u'<ul class="placeholder"><li>place holder</li></ul>')# the local node infoself.wview(vid,self.cw_rset,row=row,col=col,**morekwargs)ifis_openandnotis_leaf:# => rql is definedself.wview(parentvid,itree.children(entities=False),subvid=vid,treeid=treeid,initial_load=False,**morekwargs)w(u'</li>')