"""Specific views for entities implementing IProgress: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.interfacesimportIProgress,IMileStonefromcubicweb.schemaimportdisplay_namefromcubicweb.common.viewimportEntityViewfromcubicweb.common.selectorsimportimplement_interface,acceptfromcubicweb.web.htmlwidgetsimportProgressBarWidgetclassProgressTableView(EntityView):"""The progress table view is able to display progress information of any object implement IMileStone. The default layout is composoed of 7 columns : parent task, milestone, state, estimated date, cost, progressbar, and todo_by The view accepts an optional ``columns`` paramater that lets you remove or reorder some of those columns. To add new columns, you should extend this class, define a new ``columns`` class attribute and implement corresponding build_COLNAME_cell methods header_for_COLNAME methods allow to customize header's label """id='progress_table_view'title=_('task progression')__selectors__=(accept,implement_interface)accepts_interfaces=(IMileStone,)# default columns of the tablecolumns=(_('project'),_('milestone'),_('state'),_('eta_date'),_('cost'),_('progress'),_('todo_by'))defcall(self,columns=None):"""displays all versions in a table"""self.req.add_css('cubicweb.iprogress.css')_=self.req._self.columns=columnsorself.columnsecls=self.vreg.etype_class(self.rset.description[0][0])self.w(u'<table class="progress">')self.table_header(ecls)self.w(u'<tbody>')forrowinxrange(self.rset.rowcount):self.cell_call(row=row,col=0)self.w(u'</tbody>')self.w(u'</table>')defcell_call(self,row,col):_=self.req._entity=self.entity(row,col)infos={}forcolinself.columns:meth=getattr(self,'build_%s_cell'%col,None)# find the build method or try to find matching attributeifmeth:content=meth(entity)else:content=entity.printable_value(col)infos[col]=contentifhasattr(entity,'progress_class'):cssclass=entity.progress_class()else:cssclass=u''self.w(u"""<tr class="%s" onmouseover="addElementClass(this, 'highlighted');" onmouseout="removeElementClass(this, 'highlighted')">"""%cssclass)line=u''.join(u'<td>%%(%s)s</td>'%colforcolinself.columns)self.w(line%infos)self.w(u'</tr>\n')## header management ######################################################defheader_for_project(self,ecls):"""use entity's parent type as label"""returndisplay_name(self.req,ecls.parent_type)defheader_for_milestone(self,ecls):"""use entity's type as label"""returndisplay_name(self.req,ecls.id)deftable_header(self,ecls):"""builds the table's header"""self.w(u'<thead><tr>')_=self.req._forcolumninself.columns:meth=getattr(self,'header_for_%s'%column,None)ifmeth:colname=meth(ecls)else:colname=_(column)self.w(u'<th>%s</th>'%html_escape(colname))self.w(u'</tr></thead>\n')## cell management ########################################################defbuild_project_cell(self,entity):"""``project`` column cell renderer"""project=entity.get_main_task()ifproject:returnproject.view('incontext')returnself.req._('no related project')defbuild_milestone_cell(self,entity):"""``milestone`` column cell renderer"""returnentity.view('incontext')defbuild_state_cell(self,entity):"""``state`` column cell renderer"""returnhtml_escape(self.req._(entity.state))defbuild_eta_date_cell(self,entity):"""``eta_date`` column cell renderer"""ifentity.finished():returnself.format_date(entity.completion_date())formated_date=self.format_date(entity.initial_prevision_date())ifentity.in_progress():eta_date=self.format_date(entity.eta_date())_=self.req._ifformated_date:formated_date+=u' (%s%s)'%(_('expected:'),eta_date)else:formated_date=u'%s%s'%(_('expected:'),eta_date)returnformated_datedefbuild_todo_by_cell(self,entity):"""``todo_by`` column cell renderer"""returnu', '.join(p.view('outofcontext')forpinentity.contractors())defbuild_cost_cell(self,entity):"""``cost`` column cell renderer"""_=self.req._pinfo=entity.progress_info()totalcost=pinfo.get('estimatedcorrected',pinfo['estimated'])missing=pinfo.get('notestimatedcorrected',pinfo.get('notestimated',0))costdescr=[]ifmissing:# XXX: link to unestimated entitiescostdescr.append(_('%s not estimated')%missing)estimated=pinfo['estimated']ifestimatedandestimated!=totalcost:costdescr.append(_('initial estimation %s')%estimated)ifcostdescr:returnu'%s (%s)'%(totalcost,', '.join(costdescr))returnunicode(totalcost)defbuild_progress_cell(self,entity):"""``progress`` column cell renderer"""progress=u'<div class="progress_data">%s (%.2f%%)</div>'%(entity.done,entity.progress())returnprogress+entity.view('progressbar')classInContextProgressTableView(ProgressTableView):"""this views redirects to ``progress_table_view`` but removes the ``project`` column """id='ic_progress_table_view'defcall(self):view=self.vreg.select_view('progress_table_view',self.req,self.rset)columns=list(view.columns)try:columns.remove('project')exceptValueError:self.info('[ic_progress_table_view] could not remove project from columns')view.dispatch(w=self.w,columns=columns)classProgressBarView(EntityView):"""displays a progress bar"""id='progressbar'title=_('progress bar')__selectors__=(accept,implement_interface)accepts_interfaces=(IProgress,)defcell_call(self,row,col):self.req.add_css('cubicweb.iprogress.css')entity=self.entity(row,col)widget=ProgressBarWidget(entity.done,entity.todo,entity.revised_cost)self.w(widget.render())