[transaction] move RQLRewriter in Transaction
This remove the last ``AttributeError`` magic. The ``RQLRewriter`` needs a Session. Its
reset is handled in ``Session`` code to handle that
# copyright 2003-2012 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/>."""base classes to handle tabbed views"""__docformat__="restructuredtext en"_=unicodefromlogilab.common.deprecationimportclass_renamedfromlogilab.mtconverterimportxml_escapefromcubicwebimportNoSelectableObject,rolefromcubicwebimporttags,uilib,utilsfromcubicweb.predicatesimportpartial_has_related_entitiesfromcubicweb.viewimportEntityViewfromcubicweb.web.viewsimportprimaryclassLazyViewMixin(object):"""provides two convenience methods for the tab machinery. Can also be used to lazy-load arbitrary views. """def_prepare_bindings(self,vid,reloadable):self._cw.add_onload(u""" jQuery('#lazy-%(vid)s').bind('%(event)s', function(event) { loadNow('#lazy-%(vid)s', '#%(vid)s-hole', %(reloadable)s); });"""%{'event':'load_%s'%vid,'vid':vid,'reloadable':str(reloadable).lower()})deflazyview(self,vid,rql=None,eid=None,rset=None,tabid=None,reloadable=False,show_spinbox=True,w=None):"""a lazy version of wview"""w=worself.wself._cw.add_js('cubicweb.ajax.js')# the form is copied into urlparams to please the inner views# that might want to take params from it# beware of already present rql or eid elements# to be safe of collision a proper argument passing protocol# (with namespaces) should be used instead of the current# ad-hockeryurlparams=self._cw.form.copy()urlparams.pop('rql',None)urlparams.pop('eid',None)urlparams.update({'vid':vid,'fname':'view'})ifrql:urlparams['rql']=rqlelifeid:urlparams['eid']=eidelifrset:urlparams['rql']=rset.printable_rql()iftabidisNone:tabid=uilib.domid(vid)w(u'<div id="lazy-%s" cubicweb:loadurl="%s">'%(tabid,xml_escape(self._cw.build_url('ajax',**urlparams))))ifshow_spinbox:# Don't use ``alt`` since image is a *visual* helper for ajaxw(u'<img style="display: none" src="%s" alt="" id="%s-hole"/>'%(xml_escape(self._cw.data_url('loading.gif')),tabid))else:w(u'<div id="%s-hole"></div>'%tabid)w(u'<noscript><p>%s <a id="seo-%s" href="%s">%s</a></p></noscript>'%(xml_escape(self._cw._('Link:')),tabid,xml_escape(self._cw.build_url(**urlparams)),xml_escape(self._cw._(tabid))))w(u'</div>')self._prepare_bindings(tabid,reloadable)defforceview(self,vid):"""trigger an event that will force immediate loading of the view on dom readyness """self._cw.add_onload(uilib.js.triggerLoad(vid))classTabsMixin(LazyViewMixin):"""a tab mixin to easily get jQuery based, lazy, ajax tabs"""lazy=True@propertydefcookie_name(self):returnstr('%s_active_tab'%self._cw.vreg.config.appid)defactive_tab(self,default):if'tab'inself._cw.form:returnself._cw.form['tab']cookies=self._cw.get_cookie()cookiename=self.cookie_nameactivetab=cookies.get(cookiename)ifactivetabisNone:domid=uilib.domid(default)self._cw.set_cookie(cookiename,domid)returndomidreturnactivetab.valuedefprune_tabs(self,tabs,default_tab):selected_tabs=[]may_be_active_tab=self.active_tab(default_tab)active_tab=uilib.domid(default_tab)viewsvreg=self._cw.vreg['views']fortabintabs:ifisinstance(tab,basestring):tabid,tabkwargs=tab,{}else:tabid,tabkwargs=tabtabkwargs=tabkwargs.copy()tabkwargs.setdefault('rset',self.cw_rset)vid=tabkwargs.get('vid',tabid)domid=uilib.domid(tabid)try:viewsvreg.select(vid,self._cw,tabid=domid,**tabkwargs)exceptNoSelectableObject:continueselected_tabs.append((tabid,domid,tabkwargs))ifdomid==may_be_active_tab:active_tab=domidreturnselected_tabs,active_tabdefrender_tabs(self,tabs,default,entity=None):# delegate to the default tab if there is more than one entity# in the result set (tabs are pretty useless there)ifentityandlen(self.cw_rset)>1:entity.view(default,w=self.w)returnself._cw.add_css('jquery.ui.css')self._cw.add_js(('jquery.ui.js','cubicweb.ajax.js','jquery.cookie.js'))# prune tabs : not all are to be showntabs,active_tab=self.prune_tabs(tabs,default)# build the html structurew=self.wuid=entityandentity.eidorutils.make_uid('tab')w(u'<div id="entity-tabs-%s">'%uid)w(u'<ul>')active_tab_idx=Nonefori,(tabid,domid,tabkwargs)inenumerate(tabs):w(u'<li>')w(u'<a href="#%s">'%domid)w(tabkwargs.pop('label',self._cw._(tabid)))w(u'</a>')w(u'</li>')ifdomid==active_tab:active_tab_idx=iw(u'</ul>')fortabid,domid,tabkwargsintabs:w(u'<div id="%s">'%domid)ifself.lazy:tabkwargs.setdefault('tabid',domid)tabkwargs.setdefault('vid',tabid)self.lazyview(**tabkwargs)else:self._cw.view(tabid,w=self.w,**tabkwargs)w(u'</div>')w(u'</div>')# call the setTab() JS function *after* each tab is generated# because the callback binding needs to be done before# XXX make work history: trueifself.lazy:self._cw.add_onload(u""" jQuery('#entity-tabs-%(uid)s').tabs( { selected: %(tabindex)s, select: function(event, ui) { setTab(ui.panel.id, '%(cookiename)s'); } }); setTab('%(domid)s', '%(cookiename)s');"""%{'tabindex':active_tab_idx,'domid':active_tab,'uid':uid,'cookiename':self.cookie_name})else:self._cw.add_onload(u"jQuery('#entity-tabs-%(uid)s').tabs({selected: %(tabindex)s});"%{'tabindex':active_tab_idx,'uid':uid})classEntityRelationView(EntityView):"""view displaying entity related stuff. Such a view _must_ provide the rtype, target and vid attributes : Example : class ProjectScreenshotsView(EntityRelationView): '''display project's screenshots''' __regid__ = title = _('projectscreenshots') __select__ = EntityRelationView.__select__ & is_instance('Project') rtype = 'screenshot' role = 'subject' vid = 'gallery' in this example, entities related to project entity by the 'screenshot' relation (where the project is subject of the relation) will be displayed using the 'gallery' view. """__select__=EntityView.__select__&partial_has_related_entities()vid='list'# to be defined in concrete classesrtype=title=Nonedefcell_call(self,row,col):rset=self.cw_rset.get_entity(row,col).related(self.rtype,role(self))self.w(u'<div class="mainInfo">')ifself.title:self.w(tags.h1(self._cw._(self.title)))self.wview(self.vid,rset,'noresult')self.w(u'</div>')classTabbedPrimaryView(TabsMixin,primary.PrimaryView):__abstract__=True# don't registertabs=[_('main_tab')]default_tab='main_tab'defrender_entity(self,entity):self.render_entity_toolbox(entity)self.w(u'<div class="tabbedprimary"></div>')self.render_entity_title(entity)self.render_tabs(self.tabs,self.default_tab,entity)TabedPrimaryView=class_renamed('TabedPrimaryView',TabbedPrimaryView)classPrimaryTab(primary.PrimaryView):__regid__='main_tab'title=None# should not appear in possible viewsdefis_primary(self):returnTruedefrender_entity_title(self,entity):passdefrender_entity_toolbox(self,entity):pass