[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/>."""Specific views for CWProperty (eg site/user preferences"""__docformat__="restructuredtext en"_=unicodefromlogilab.mtconverterimportxml_escapefromlogilab.common.decoratorsimportcachedfromcubicwebimportUnknownPropertyfromcubicweb.selectorsimport(one_line_rset,none_rset,is_instance,match_user_groups,objectify_selector,logged_user_in_rset)fromcubicweb.viewimportStartupViewfromcubicweb.webimportuicfg,stdmsgsfromcubicweb.web.formimportFormViewMixInfromcubicweb.web.formfieldsimportFIELDS,StringFieldfromcubicweb.web.formwidgetsimport(Select,TextInput,Button,SubmitButton,FieldWidget)fromcubicweb.web.viewsimportprimary,formrenderers,editcontrolleruicfg.primaryview_section.tag_object_of(('*','for_user','*'),'hidden')# some string we want to be internationalizable for nicer display of property# groups_('navigation')_('ui')_('boxes')_('components')_('ctxcomponents')_('navigation.combobox-limit')_('navigation.page-size')_('navigation.related-limit')_('navigation.short-line-size')_('ui.date-format')_('ui.datetime-format')_('ui.default-text-format')_('ui.fckeditor')_('ui.float-format')_('ui.language')_('ui.time-format')_('open all')_('ui.main-template')_('ui.site-title')_('ui.encoding')_('category')defmake_togglable_link(nodeid,label):"""builds a HTML link that switches the visibility & remembers it"""returnu'<a href="javascript: togglePrefVisibility(\'%s\')">%s</a>'%(nodeid,label)defcss_class(someclass):returnsomeclassand'class="%s"'%someclassor''classCWPropertyPrimaryView(primary.PrimaryView):__select__=is_instance('CWProperty')skip_none=FalseclassSystemCWPropertiesForm(FormViewMixIn,StartupView):"""site-wide properties edition form"""__regid__='systempropertiesform'__select__=none_rset()&match_user_groups('managers')form_buttons=[SubmitButton()]title=_('site configuration')category='startupview'deflinkable(self):returnTruedefurl(self):"""return the url associated with this view. We can omit rql here"""returnself._cw.build_url('view',vid=self.__regid__)def_cookie_name(self,somestr):returnstr('%s_property_%s'%(self._cw.vreg.config.appid,somestr))def_group_status(self,group,default=u'hidden'):"""return css class name 'hidden' (collapsed), or '' (open)"""cookies=self._cw.get_cookie()cookiename=self._cookie_name(group)cookie=cookies.get(cookiename)ifcookieisNone:self._cw.set_cookie(cookiename,default,maxage=None)status=defaultelse:status=cookie.valuereturnstatusdefcall(self,**kwargs):self._cw.add_js(('cubicweb.preferences.js','cubicweb.edition.js','cubicweb.ajax.js'))self._cw.add_css('cubicweb.preferences.css')vreg=self._cw.vregvalues=self.defined_keysgroupedopts={}mainopts={}# "self.id=='systempropertiesform'" to skip site wide properties on# user's preference but not site's configurationforkeyinvreg.user_property_keys(self.__regid__=='systempropertiesform'):parts=key.split('.')ifparts[0]invregandlen(parts)>=3:# appobject configurationreg=parts[0]propid=parts[-1]oid='.'.join(parts[1:-1])groupedopts.setdefault(reg,{}).setdefault(oid,[]).append(key)else:mainopts.setdefault(parts[0],[]).append(key)# precompute form to consume error messageforgroup,keysinmainopts.items():mainopts[group]=self.form(group,keys,False)forgroup,objectsingroupedopts.items():foroid,keysinobjects.items():groupedopts[group][oid]=self.form(group+'_'+oid,keys,True)w=self.wreq=self._cw_=req._w(u'<h1>%s</h1>\n'%_(self.title))forlabel,group,forminsorted((_(g),g,f)forg,finmainopts.iteritems()):status=css_class(self._group_status(group))w(u'<div class="propertiesform">%s</div>\n'%(make_togglable_link('fieldset_'+group,label.capitalize())))w(u'<div id="fieldset_%s" %s>'%(group,status))w(u'<fieldset class="preferences">')w(form)w(u'</fieldset></div>')forlabel,group,objectsinsorted((_(g),g,o)forg,oingroupedopts.iteritems()):status=css_class(self._group_status(group))w(u'<div class="propertiesform">%s</div>\n'%(make_togglable_link('fieldset_'+group,label.capitalize())))w(u'<div id="fieldset_%s" %s>'%(group,status))# create selectionsorted_objects=sorted((self._cw.__('%s_%s'%(group,o)),o,f)foro,finobjects.iteritems())forlabel,oid,forminsorted_objects:w(u'<div class="component">')w(u'''<div class="componentLink"><a href="javascript:$.noop();" onclick="javascript:toggleVisibility('field_%(oid)s_%(group)s')" class="componentTitle">%(label)s</a>'''%{'label':label,'oid':oid,'group':group})w(u''' (<div class="openlink"><a href="javascript:$.noop();" onclick="javascript:openFieldset('fieldset_%(group)s')">%(label)s</a></div>)'''%{'label':_('open all'),'group':group})w(u'</div>')docmsgid='%s_%s_description'%(group,oid)doc=_(docmsgid)ifdoc!=docmsgid:w(u'<div class="helper">%s</div>'%xml_escape(doc).capitalize())w(u'</div>')w(u'<fieldset id="field_%(oid)s_%(group)s" class="%(group)s preferences hidden">'%{'oid':oid,'group':group})w(form)w(u'</fieldset>')w(u'</div>')@property@cacheddefcwprops_rset(self):returnself._cw.execute('Any P,K,V WHERE P is CWProperty, P pkey K, ''P value V, NOT P for_user U')@propertydefdefined_keys(self):values={}fori,entityinenumerate(self.cwprops_rset.entities()):values[entity.pkey]=ireturnvaluesdefentity_for_key(self,key):values=self.defined_keysifkeyinvalues:entity=self.cwprops_rset.get_entity(values[key],0)else:entity=self._cw.vreg['etypes'].etype_class('CWProperty')(self._cw)entity.eid=self._cw.varmaker.next()entity.cw_attr_cache['pkey']=keyentity.cw_attr_cache['value']=self._cw.vreg.property_value(key)returnentitydefform(self,formid,keys,splitlabel=False):form=self._cw.vreg['forms'].select('composite',self._cw,domid=formid,action=self._cw.build_url(),form_buttons=self.form_buttons,onsubmit="return validatePrefsForm('%s')"%formid,submitmsg=self._cw._('changes applied'))path=self._cw.relative_path()if'?'inpath:path,params=path.split('?',1)form.add_hidden('__redirectparams',params)form.add_hidden('__redirectpath',path)forkeyinkeys:self.form_row(form,key,splitlabel)renderer=self._cw.vreg['formrenderers'].select('cwproperties',self._cw,display_progress_div=False)data=[]form.render(w=data.append,renderer=renderer)returnu'\n'.join(data)defform_row(self,form,key,splitlabel):entity=self.entity_for_key(key)ifsplitlabel:label=key.split('.')[-1]else:label=keysubform=self._cw.vreg['forms'].select('base',self._cw,entity=entity,mainform=False)subform.append_field(PropertyValueField(name='value',label=label,role='subject',eidparam=True))#subform.vreg = self._cw.vregsubform.add_hidden('pkey',key,eidparam=True,role='subject')form.add_subform(subform)returnsubformclassCWPropertiesForm(SystemCWPropertiesForm):"""user's preferences properties edition form"""__regid__='propertiesform'__select__=((none_rset()&match_user_groups('users','managers'))|(one_line_rset()&match_user_groups('users')&logged_user_in_rset())|(one_line_rset()&match_user_groups('managers')&is_instance('CWUser')))title=_('user preferences')@propertydefuser(self):ifself.cw_rsetisNone:returnself._cw.userreturnself.cw_rset.get_entity(self.cw_rowor0,self.cw_color0)@property@cacheddefcwprops_rset(self):returnself._cw.execute('Any P,K,V WHERE P is CWProperty, P pkey K, P value V,''P for_user U, U eid %(x)s',{'x':self.user.eid})defform_row(self,form,key,splitlabel):subform=super(CWPropertiesForm,self).form_row(form,key,splitlabel)# if user is in the managers group and the property is being created,# we have to set for_user explicitlyifnotsubform.edited_entity.has_eid()andself.user.matching_groups('managers'):subform.add_hidden('for_user',self.user.eid,eidparam=True,role='subject')# cwproperty form objects ######################################################classPlaceHolderWidget(FieldWidget):defrender(self,form,field,renderer):domid=field.dom_id(form)# empty span as well else html validation fail (label is refering to# this id)return'<div id="div:%s"><span id="%s">%s</span></div>'%(domid,domid,form._cw._('select a key first'))classNotEditableWidget(FieldWidget):def__init__(self,value,msg=None):self.value=valueself.msg=msgdefrender(self,form,field,renderer):domid=field.dom_id(form)value='<span class="value" id="%s">%s</span>'%(domid,self.value)ifself.msg:value+'<div class="helper">%s</div>'%self.msgreturnvalueclassPropertyKeyField(StringField):"""specific field for CWProperty.pkey to set the value widget according to the selected key """widget=Selectdefrender(self,form,renderer):wdg=self.get_widget(form)# pylint: disable=E1101wdg.attrs['tabindex']=form._cw.next_tabindex()wdg.attrs['onchange']="javascript:setPropValueWidget('%s', %s)"%(form.edited_entity.eid,form._cw.next_tabindex())returnwdg.render(form,self,renderer)defvocabulary(self,form):entity=form.edited_entity_=form._cw._ifentity.has_eid():return[(_(entity.pkey),entity.pkey)]choices=entity._cw.vreg.user_property_keys()return[(u'',u'')]+sorted(zip((_(v)forvinchoices),choices))classPropertyValueField(StringField):"""specific field for CWProperty.value which will be different according to the selected key type and vocabulary information """widget=PlaceHolderWidgetdefrender(self,form,renderer=None,tabindex=None):wdg=self.get_widget(form)iftabindexisnotNone:wdg.attrs['tabindex']=tabindexreturnwdg.render(form,self,renderer)defform_init(self,form):entity=form.edited_entityifnot(entity.has_eid()or'pkey'inentity.cw_attr_cache):# no key set yet, just include an empty div which will be filled# on key selectionreturntry:pdef=form._cw.vreg.property_info(entity.pkey)exceptUnknownProperty,ex:form.warning('%s (you should probably delete that property ''from the database)',ex)msg=form._cw._('you should probably delete that property')self.widget=NotEditableWidget(entity.printable_value('value'),'%s (%s)'%(msg,ex))ifentity.pkey.startswith('system.'):msg=form._cw._('value associated to this key is not editable ''manually')self.widget=NotEditableWidget(entity.printable_value('value'),msg)# XXX race condition when used from CWPropertyForm, should not rely on# instance attributesself.value=pdef['default']self.help=pdef['help']vocab=pdef['vocabulary']ifvocabisnotNone:ifcallable(vocab):# list() just in case its a generator functionself.choices=list(vocab())else:self.choices=vocabwdg=Select()elifpdef['type']=='String':# else we'll get a TextArea by defaultwdg=TextInput()else:field=FIELDS[pdef['type']]()wdg=field.widgetifpdef['type']=='Boolean':self.choices=field.vocabulary(form)self.widget=wdgclassCWPropertiesFormRenderer(formrenderers.FormRenderer):"""specific renderer for properties"""__regid__='cwproperties'defopen_form(self,form,values):err='<div class="formsg"></div>'returnsuper(CWPropertiesFormRenderer,self).open_form(form,values)+errdef_render_fields(self,fields,w,form):forfieldinfields:w(u'<div class="preffield">\n')ifself.display_label:w(u'%s'%self.render_label(form,field))error=form.field_error(field)iferror:w(u'<span class="error">%s</span>'%error)w(u'%s'%self.render_help(form,field))w(u'<div class="prefinput">')w(field.render(form,self))w(u'</div>')w(u'</div>')defrender_buttons(self,w,form):w(u'<div>\n')forbuttoninform.form_buttons:w(u'%s\n'%button.render(form))w(u'</div>')classCWPropertyIEditControlAdapter(editcontroller.IEditControlAdapter):__select__=is_instance('CWProperty')defafter_deletion_path(self):"""return (path, parameters) which should be used as redirect information when this entity is being deleted """return'view',{}_afs=uicfg.autoform_section_afs.tag_subject_of(('*','for_user','*'),'main','hidden')_afs.tag_object_of(('*','for_user','*'),'main','hidden')_aff=uicfg.autoform_field_aff.tag_attribute(('CWProperty','pkey'),PropertyKeyField)_aff.tag_attribute(('CWProperty','value'),PropertyValueField)