"""generic boxes for CubicWeb web client:* actions box* possible views box* rss iconadditional (disabled by default) boxes* schema box* startup views box:organization: Logilab:copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.:contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr"""__docformat__="restructuredtext en"fromlogilab.mtconverterimporthtml_escapefromcubicweb.common.selectorsimport(any_rset,appobject_selectable)fromcubicweb.web.htmlwidgetsimportBoxWidget,BoxMenu,BoxHtml,RawBoxItemfromcubicweb.web.boximportBoxTemplate,ExtResourcesBoxTemplate_=unicodeclassEditBox(BoxTemplate):""" box with all actions impacting the entity displayed: edit, copy, delete change state, add related entities """__selectors__=(any_rset,)+BoxTemplate.__selectors__id='edit_box'title=_('actions')order=2defcall(self,**kwargs):_=self.req._title=_(self.title)ifself.rset:etypes=self.rset.column_types(0)iflen(etypes)==1:plural=self.rset.rowcount>1and'plural'or''etypelabel=display_name(self.req,iter(etypes).next(),plural)title=u'%s - %s'%(title,etypelabel.lower())box=BoxWidget(title,self.id,_class="greyBoxFrame")# build list of actionsactions=self.vreg.possible_actions(self.req,self.rset)add_menu=BoxMenu(_('add'))# 'addrelated' categoryother_menu=BoxMenu(_('more actions'))# 'moreactions' categorysearchstate=self.req.search_state[0]forcategory,menuin(('mainactions',box),('addrelated',add_menu),('moreactions',other_menu)):foractioninactions.get(category,()):menu.append(self.box_action(action))ifself.rsetandself.rset.rowcount==1and \notself.schema[self.rset.description[0][0]].is_final()and \searchstate=='normal':entity=self.rset.get_entity(0,0)#entity.complete()ifadd_menu.items:self.info('explicit actions defined, ignoring potential rtags for %s',entity.e_schema)else:# some addrelated actions may be specified but no one is selectable# in which case we should not fallback to schema_actions. The proper# way to avoid this is to override add_related_schemas() on the# entity class to return an empty listforactioninself.schema_actions(entity):add_menu.append(action)self.workflow_actions(entity,box)ifbox.is_empty()andnotother_menu.is_empty():box.items=other_menu.itemsother_menu.items=[]self.add_submenu(box,add_menu,_('add'))self.add_submenu(box,other_menu)ifnotbox.is_empty():box.render(self.w)defadd_submenu(self,box,submenu,label_prefix=None):iflen(submenu.items)==1:boxlink=submenu.items[0]iflabel_prefix:boxlink.label=u'%s%s'%(label_prefix,boxlink.label)box.append(boxlink)elifsubmenu.items:box.append(submenu)defschema_actions(self,entity):user=self.req.useractions=[]_=self.req._eschema=entity.e_schemaforrschema,teschema,xinentity.add_related_schemas():ifx=='subject':label='add %s%s%s%s'%(eschema,rschema,teschema,x)url=self.linkto_url(entity,rschema,teschema,'object')else:label='add %s%s%s%s'%(teschema,rschema,eschema,x)url=self.linkto_url(entity,rschema,teschema,'subject')actions.append(self.mk_action(_(label),url))returnactionsdefworkflow_actions(self,entity,box):if'in_state'inentity.e_schema.subject_relations()andentity.in_state:_=self.req._state=entity.in_state[0]transitions=list(state.transitions(entity))iftransitions:menu_title=u'%s: %s'%(_('state'),state.view('text'))menu_items=[]fortrinstate.transitions(entity):url=entity.absolute_url(vid='statuschange',treid=tr.eid)menu_items.append(self.mk_action(_(tr.name),url))box.append(BoxMenu(menu_title,menu_items))# when there are no possible transition, put state if the menu if# there are some other actionselifnotbox.is_empty():menu_title=u'<a title="%s">%s: <i>%s</i></a>'%(_('no possible transition'),_('state'),state.view('text'))box.append(RawBoxItem(menu_title,'boxMainactions'))returnNonedeflinkto_url(self,entity,rtype,etype,target):returnself.build_url(vid='creation',etype=etype,__linkto='%s:%s:%s'%(rtype,entity.eid,target),__redirectpath=entity.rest_path(),# should not be url quoted!__redirectvid=self.req.form.get('vid',''))classSearchBox(BoxTemplate):"""display a box with a simple search form"""id='search_box'visible=True# enabled by defaulttitle=_('search')order=0need_resources='SEARCH_GO'formdef=u"""<form action="%s"><table id="tsearch"><tr><td><input id="norql" type="text" accesskey="q" tabindex="%s" title="search text" value="%s" name="rql" /><input type="hidden" name="__fromsearchbox" value="1" /><input type="hidden" name="subvid" value="tsearch" /></td><td><input tabindex="%s" type="submit" id="rqlboxsubmit" value="" /></td></tr></table></form>"""defcall(self,view=None,**kwargs):req=self.reqifreq.form.pop('__fromsearchbox',None):rql=req.form.get('rql','')else:rql=''form=self.formdef%(req.build_url('view'),req.next_tabindex(),html_escape(rql),req.next_tabindex())title=u"""<span onclick="javascript: toggleVisibility('rqlinput')">%s</span>"""%req._(self.title)box=BoxWidget(title,self.id,_class="searchBoxFrame",islist=False,escape=False)box.append(BoxHtml(form))box.render(self.w)# boxes disabled by default ###################################################classPossibleViewsBox(BoxTemplate):"""display a box containing links to all possible views"""id='possible_views_box'title=_('possible views')order=10require_groups=('users','managers')visible=Falsedefcall(self,**kwargs):box=BoxWidget(self.req._(self.title),self.id)actions=[vforvinself.vreg.possible_views(self.req,self.rset)ifv.category!='startupview']forcategory,actionsinself.sort_actions(actions):menu=BoxMenu(category)foractioninactions:menu.append(self.box_action(action))box.append(menu)ifnotbox.is_empty():box.render(self.w)classRSSIconBox(ExtResourcesBoxTemplate):"""just display the RSS icon on uniform result set"""__selectors__=ExtResourcesBoxTemplate.__selectors__+(appobject_selectable('components','rss_feed_url'),)id='rss'order=999need_resources='RSS_LOGO',visible=Falsedefcall(self,**kwargs):urlgetter=self.vreg.select_component('rss_feed_url',self.req,self.rset)url=urlgetter.feed_url()rss=self.req.external_resource('RSS_LOGO')self.w(u'<a href="%s"><img src="%s" border="0" /></a>\n'%(html_escape(url),rss))## warning("schemabox ne marche plus pour le moment")## class SchemaBox(BoxTemplate):## """display a box containing link to list of entities by type"""## id = 'schema_box'## visible = False # disabled by default## title = _('entity list')## order = 60## def call(self, **kwargs):## box = BoxWidget(self.req._(title), self.id)## for etype in self.config.etypes(self.req.user, 'read'):## view = self.vreg.select_view('list', self.req, self.etype_rset(etype))## box.append(self.mk_action(display_name(self.req, etype, 'plural'),## view.url(), etype=etype))## if not box.is_empty():## box.render(self.w)classStartupViewsBox(BoxTemplate):"""display a box containing links to all startup views"""id='startup_views_box'visible=False# disabled by defaulttitle=_('startup views')order=70defcall(self,**kwargs):box=BoxWidget(self.req._(self.title),self.id)forviewinself.vreg.possible_views(self.req,None):ifview.category=='startupview':box.append(self.box_action(view))ifnotbox.is_empty():box.render(self.w)