67 _('%d hours') |
67 _('%d hours') |
68 _('%d minutes') |
68 _('%d minutes') |
69 _('%d seconds') |
69 _('%d seconds') |
70 |
70 |
71 def cell_call(self, row, col, props=None, format='text/html'): |
71 def cell_call(self, row, col, props=None, format='text/html'): |
72 etype = self.rset.description[row][col] |
72 etype = self.cw_rset.description[row][col] |
73 value = self.rset.rows[row][col] |
73 value = self.cw_rset.rows[row][col] |
74 |
74 |
75 if etype == 'String': |
75 if etype == 'String': |
76 entity, rtype = self.rset.related_entity(row, col) |
76 entity, rtype = self.cw_rset.related_entity(row, col) |
77 if entity is not None: |
77 if entity is not None: |
78 # yes ! |
78 # yes ! |
79 self.w(entity.printable_value(rtype, value, format=format)) |
79 self.w(entity.printable_value(rtype, value, format=format)) |
80 return |
80 return |
81 if etype in ('Time', 'Interval'): |
81 if etype in ('Time', 'Interval'): |
91 if format == 'text/html': |
91 if format == 'text/html': |
92 space = ' ' |
92 space = ' ' |
93 else: |
93 else: |
94 space = ' ' |
94 space = ' ' |
95 if value.days > 730: # 2 years |
95 if value.days > 730: # 2 years |
96 self.w(self.req.__('%%d%syears' % space) % (value.days // 365)) |
96 self.w(self._cw.__('%%d%syears' % space) % (value.days // 365)) |
97 elif value.days > 60: # 2 months |
97 elif value.days > 60: # 2 months |
98 self.w(self.req.__('%%d%smonths' % space) % (value.days // 30)) |
98 self.w(self._cw.__('%%d%smonths' % space) % (value.days // 30)) |
99 elif value.days > 14: # 2 weeks |
99 elif value.days > 14: # 2 weeks |
100 self.w(self.req.__('%%d%sweeks' % space) % (value.days // 7)) |
100 self.w(self._cw.__('%%d%sweeks' % space) % (value.days // 7)) |
101 elif value.days > 2: |
101 elif value.days > 2: |
102 self.w(self.req.__('%%d%sdays' % space) % int(value.days)) |
102 self.w(self._cw.__('%%d%sdays' % space) % int(value.days)) |
103 elif value.seconds > 3600: |
103 elif value.seconds > 3600: |
104 self.w(self.req.__('%%d%shours' % space) % int(value.seconds // 3600)) |
104 self.w(self._cw.__('%%d%shours' % space) % int(value.seconds // 3600)) |
105 elif value.seconds >= 120: |
105 elif value.seconds >= 120: |
106 self.w(self.req.__('%%d%sminutes' % space) % int(value.seconds // 60)) |
106 self.w(self._cw.__('%%d%sminutes' % space) % int(value.seconds // 60)) |
107 else: |
107 else: |
108 self.w(self.req.__('%%d%sseconds' % space) % int(value.seconds)) |
108 self.w(self._cw.__('%%d%sseconds' % space) % int(value.seconds)) |
109 return |
109 return |
110 self.wdata(printable_value(self.req, etype, value, props)) |
110 self.wdata(printable_value(self._cw, etype, value, props)) |
111 |
111 |
112 |
112 |
113 # XXX deprecated |
113 # XXX deprecated |
114 class SecondaryView(EntityView): |
114 class SecondaryView(EntityView): |
115 __regid__ = 'secondary' |
115 __regid__ = 'secondary' |
117 |
117 |
118 def cell_call(self, row, col): |
118 def cell_call(self, row, col): |
119 """the secondary view for an entity |
119 """the secondary view for an entity |
120 secondary = icon + view(oneline) |
120 secondary = icon + view(oneline) |
121 """ |
121 """ |
122 entity = self.rset.get_entity(row, col) |
122 entity = self.cw_rset.get_entity(row, col) |
123 self.w(u' ') |
123 self.w(u' ') |
124 self.wview('oneline', self.rset, row=row, col=col) |
124 self.wview('oneline', self.cw_rset, row=row, col=col) |
125 |
125 |
126 |
126 |
127 class OneLineView(EntityView): |
127 class OneLineView(EntityView): |
128 __regid__ = 'oneline' |
128 __regid__ = 'oneline' |
129 title = _('oneline') |
129 title = _('oneline') |
130 |
130 |
131 def cell_call(self, row, col): |
131 def cell_call(self, row, col): |
132 """the one line view for an entity: linked text view |
132 """the one line view for an entity: linked text view |
133 """ |
133 """ |
134 entity = self.rset.get_entity(row, col) |
134 entity = self.cw_rset.get_entity(row, col) |
135 self.w(u'<a href="%s">' % xml_escape(entity.absolute_url())) |
135 self.w(u'<a href="%s">' % xml_escape(entity.absolute_url())) |
136 self.w(xml_escape(self.view('text', self.rset, row=row, col=col))) |
136 self.w(xml_escape(self._cw.view('text', self.cw_rset, row=row, col=col))) |
137 self.w(u'</a>') |
137 self.w(u'</a>') |
138 |
138 |
139 |
139 |
140 class TextView(EntityView): |
140 class TextView(EntityView): |
141 """the simplest text view for an entity""" |
141 """the simplest text view for an entity""" |
168 """paragraph view of some metadata""" |
168 """paragraph view of some metadata""" |
169 __regid__ = 'metadata' |
169 __regid__ = 'metadata' |
170 show_eid = True |
170 show_eid = True |
171 |
171 |
172 def cell_call(self, row, col): |
172 def cell_call(self, row, col): |
173 _ = self.req._ |
173 _ = self._cw._ |
174 entity = self.rset.get_entity(row, col) |
174 entity = self.cw_rset.get_entity(row, col) |
175 self.w(u'<div class="metadata">') |
175 self.w(u'<div class="metadata">') |
176 if self.show_eid: |
176 if self.show_eid: |
177 self.w(u'#%s - ' % entity.eid) |
177 self.w(u'#%s - ' % entity.eid) |
178 if entity.modification_date != entity.creation_date: |
178 if entity.modification_date != entity.creation_date: |
179 self.w(u'<span>%s</span> ' % _('latest update on')) |
179 self.w(u'<span>%s</span> ' % _('latest update on')) |
180 self.w(u'<span class="value">%s</span>, ' |
180 self.w(u'<span class="value">%s</span>, ' |
181 % self.format_date(entity.modification_date)) |
181 % self._cw.format_date(entity.modification_date)) |
182 # entities from external source may not have a creation date (eg ldap) |
182 # entities from external source may not have a creation date (eg ldap) |
183 if entity.creation_date: |
183 if entity.creation_date: |
184 self.w(u'<span>%s</span> ' % _('created on')) |
184 self.w(u'<span>%s</span> ' % _('created on')) |
185 self.w(u'<span class="value">%s</span>' |
185 self.w(u'<span class="value">%s</span>' |
186 % self.format_date(entity.creation_date)) |
186 % self._cw.format_date(entity.creation_date)) |
187 if entity.creator: |
187 if entity.creator: |
188 self.w(u' <span>%s</span> ' % _('by')) |
188 self.w(u' <span>%s</span> ' % _('by')) |
189 self.w(u'<span class="value">%s</span>' % entity.creator.name()) |
189 self.w(u'<span class="value">%s</span>' % entity.creator.name()) |
190 self.w(u'</div>') |
190 self.w(u'</div>') |
191 |
191 |
192 |
192 |
193 class InContextTextView(TextView): |
193 class InContextTextView(TextView): |
194 __regid__ = 'textincontext' |
194 __regid__ = 'textincontext' |
195 title = None # not listed as a possible view |
195 title = None # not listed as a possible view |
196 def cell_call(self, row, col): |
196 def cell_call(self, row, col): |
197 entity = self.rset.get_entity(row, col) |
197 entity = self.cw_rset.get_entity(row, col) |
198 self.w(entity.dc_title()) |
198 self.w(entity.dc_title()) |
199 |
199 |
200 |
200 |
201 class OutOfContextTextView(InContextTextView): |
201 class OutOfContextTextView(InContextTextView): |
202 __regid__ = 'textoutofcontext' |
202 __regid__ = 'textoutofcontext' |
203 |
203 |
204 def cell_call(self, row, col): |
204 def cell_call(self, row, col): |
205 entity = self.rset.get_entity(row, col) |
205 entity = self.cw_rset.get_entity(row, col) |
206 self.w(entity.dc_long_title()) |
206 self.w(entity.dc_long_title()) |
207 |
207 |
208 |
208 |
209 class InContextView(EntityView): |
209 class InContextView(EntityView): |
210 __regid__ = 'incontext' |
210 __regid__ = 'incontext' |
211 |
211 |
212 def cell_call(self, row, col): |
212 def cell_call(self, row, col): |
213 entity = self.rset.get_entity(row, col) |
213 entity = self.cw_rset.get_entity(row, col) |
214 desc = cut(entity.dc_description(), 50) |
214 desc = cut(entity.dc_description(), 50) |
215 self.w(u'<a href="%s" title="%s">' % ( |
215 self.w(u'<a href="%s" title="%s">' % ( |
216 xml_escape(entity.absolute_url()), xml_escape(desc))) |
216 xml_escape(entity.absolute_url()), xml_escape(desc))) |
217 self.w(xml_escape(self.view('textincontext', self.rset, |
217 self.w(xml_escape(self._cw.view('textincontext', self.cw_rset, |
218 row=row, col=col))) |
218 row=row, col=col))) |
219 self.w(u'</a>') |
219 self.w(u'</a>') |
220 |
220 |
221 |
221 |
222 class OutOfContextView(EntityView): |
222 class OutOfContextView(EntityView): |
223 __regid__ = 'outofcontext' |
223 __regid__ = 'outofcontext' |
224 |
224 |
225 def cell_call(self, row, col): |
225 def cell_call(self, row, col): |
226 entity = self.rset.get_entity(row, col) |
226 entity = self.cw_rset.get_entity(row, col) |
227 desc = cut(entity.dc_description(), 50) |
227 desc = cut(entity.dc_description(), 50) |
228 self.w(u'<a href="%s" title="%s">' % ( |
228 self.w(u'<a href="%s" title="%s">' % ( |
229 xml_escape(entity.absolute_url()), xml_escape(desc))) |
229 xml_escape(entity.absolute_url()), xml_escape(desc))) |
230 self.w(xml_escape(self.view('textoutofcontext', self.rset, |
230 self.w(xml_escape(self._cw.view('textoutofcontext', self.cw_rset, |
231 row=row, col=col))) |
231 row=row, col=col))) |
232 self.w(u'</a>') |
232 self.w(u'</a>') |
233 |
233 |
234 |
234 |
235 # list views ################################################################## |
235 # list views ################################################################## |
236 |
236 |
243 """display a list of entities by calling their <item_vid> view |
243 """display a list of entities by calling their <item_vid> view |
244 |
244 |
245 :param listid: the DOM id to use for the root element |
245 :param listid: the DOM id to use for the root element |
246 """ |
246 """ |
247 # XXX much of the behaviour here should probably be outside this view |
247 # XXX much of the behaviour here should probably be outside this view |
248 if subvid is None and 'subvid' in self.req.form: |
248 if subvid is None and 'subvid' in self._cw.form: |
249 subvid = self.req.form.pop('subvid') # consume it |
249 subvid = self._cw.form.pop('subvid') # consume it |
250 if listid: |
250 if listid: |
251 listid = u' id="%s"' % listid |
251 listid = u' id="%s"' % listid |
252 else: |
252 else: |
253 listid = u'' |
253 listid = u'' |
254 if title: |
254 if title: |
255 self.w(u'<div%s class="%s"><h4>%s</h4>\n' % (listid, klass or 'section', title)) |
255 self.w(u'<div%s class="%s"><h4>%s</h4>\n' % (listid, klass or 'section', title)) |
256 self.w(u'<ul>\n') |
256 self.w(u'<ul>\n') |
257 else: |
257 else: |
258 self.w(u'<ul%s class="%s">\n' % (listid, klass or 'section')) |
258 self.w(u'<ul%s class="%s">\n' % (listid, klass or 'section')) |
259 for i in xrange(self.rset.rowcount): |
259 for i in xrange(self.cw_rset.rowcount): |
260 self.cell_call(row=i, col=0, vid=subvid, **kwargs) |
260 self.cell_call(row=i, col=0, vid=subvid, **kwargs) |
261 self.w(u'</ul>\n') |
261 self.w(u'</ul>\n') |
262 if title: |
262 if title: |
263 self.w(u'</div>\n') |
263 self.w(u'</div>\n') |
264 |
264 |
265 def cell_call(self, row, col=0, vid=None, **kwargs): |
265 def cell_call(self, row, col=0, vid=None, **kwargs): |
266 self.w(u'<li>') |
266 self.w(u'<li>') |
267 self.wview(self.item_vid, self.rset, row=row, col=col, vid=vid, **kwargs) |
267 self.wview(self.item_vid, self.cw_rset, row=row, col=col, vid=vid, **kwargs) |
268 self.w(u'</li>\n') |
268 self.w(u'</li>\n') |
269 |
269 |
270 |
270 |
271 class ListItemView(EntityView): |
271 class ListItemView(EntityView): |
272 __regid__ = 'listitem' |
272 __regid__ = 'listitem' |
273 |
273 |
274 @property |
274 @property |
275 def redirect_vid(self): |
275 def redirect_vid(self): |
276 if self.req.search_state[0] == 'normal': |
276 if self._cw.search_state[0] == 'normal': |
277 return 'outofcontext' |
277 return 'outofcontext' |
278 return 'outofcontext-search' |
278 return 'outofcontext-search' |
279 |
279 |
280 def cell_call(self, row, col, vid=None, **kwargs): |
280 def cell_call(self, row, col, vid=None, **kwargs): |
281 if not vid: |
281 if not vid: |
282 vid = self.redirect_vid |
282 vid = self.redirect_vid |
283 try: |
283 try: |
284 self.wview(vid, self.rset, row=row, col=col, **kwargs) |
284 self.wview(vid, self.cw_rset, row=row, col=col, **kwargs) |
285 except NoSelectableObject: |
285 except NoSelectableObject: |
286 if vid == self.redirect_vid: |
286 if vid == self.redirect_vid: |
287 raise |
287 raise |
288 self.wview(self.redirect_vid, self.rset, row=row, col=col, **kwargs) |
288 self.wview(self.redirect_vid, self.cw_rset, row=row, col=col, **kwargs) |
289 |
289 |
290 |
290 |
291 class SimpleListView(ListItemView): |
291 class SimpleListView(ListItemView): |
292 """list without bullets""" |
292 """list without bullets""" |
293 __regid__ = 'simplelist' |
293 __regid__ = 'simplelist' |
300 __select__ = EntityView.__select__ & one_etype_rset() |
300 __select__ = EntityView.__select__ & one_etype_rset() |
301 item_vid = 'adaptedlistitem' |
301 item_vid = 'adaptedlistitem' |
302 |
302 |
303 @property |
303 @property |
304 def title(self): |
304 def title(self): |
305 etype = iter(self.rset.column_types(0)).next() |
305 etype = iter(self.cw_rset.column_types(0)).next() |
306 return display_name(self.req, etype, form='plural') |
306 return display_name(self._cw, etype, form='plural') |
307 |
307 |
308 def call(self, **kwargs): |
308 def call(self, **kwargs): |
309 """display a list of entities by calling their <item_vid> view""" |
309 """display a list of entities by calling their <item_vid> view""" |
310 if not 'vtitle' in self.req.form: |
310 if not 'vtitle' in self._cw.form: |
311 self.w(u'<h1>%s</h1>' % self.title) |
311 self.w(u'<h1>%s</h1>' % self.title) |
312 super(AdaptedListView, self).call(**kwargs) |
312 super(AdaptedListView, self).call(**kwargs) |
313 |
313 |
314 def cell_call(self, row, col=0, vid=None, **kwargs): |
314 def cell_call(self, row, col=0, vid=None, **kwargs): |
315 self.wview(self.item_vid, self.rset, row=row, col=col, vid=vid, **kwargs) |
315 self.wview(self.item_vid, self.cw_rset, row=row, col=col, vid=vid, **kwargs) |
316 |
316 |
317 |
317 |
318 class AdaptedListItemView(ListItemView): |
318 class AdaptedListItemView(ListItemView): |
319 __regid__ = 'adaptedlistitem' |
319 __regid__ = 'adaptedlistitem' |
320 |
320 |
322 class CSVView(SimpleListView): |
322 class CSVView(SimpleListView): |
323 __regid__ = 'csv' |
323 __regid__ = 'csv' |
324 redirect_vid = 'incontext' |
324 redirect_vid = 'incontext' |
325 |
325 |
326 def call(self, **kwargs): |
326 def call(self, **kwargs): |
327 rset = self.rset |
327 rset = self.cw_rset |
328 for i in xrange(len(rset)): |
328 for i in xrange(len(rset)): |
329 self.cell_call(i, 0, vid=kwargs.get('vid')) |
329 self.cell_call(i, 0, vid=kwargs.get('vid')) |
330 if i < rset.rowcount-1: |
330 if i < rset.rowcount-1: |
331 self.w(u", ") |
331 self.w(u", ") |
332 |
332 |
333 |
333 |
334 class TreeItemView(ListItemView): |
334 class TreeItemView(ListItemView): |
335 __regid__ = 'treeitem' |
335 __regid__ = 'treeitem' |
336 |
336 |
337 def cell_call(self, row, col): |
337 def cell_call(self, row, col): |
338 self.wview('incontext', self.rset, row=row, col=col) |
338 self.wview('incontext', self.cw_rset, row=row, col=col) |
339 |
339 |
340 class TextSearchResultView(EntityView): |
340 class TextSearchResultView(EntityView): |
341 """this view is used to display full-text search |
341 """this view is used to display full-text search |
342 |
342 |
343 It tries to highlight part of data where the search word appears. |
343 It tries to highlight part of data where the search word appears. |
345 XXX: finish me (fixed line width, fixed number of lines, CSS, etc.) |
345 XXX: finish me (fixed line width, fixed number of lines, CSS, etc.) |
346 """ |
346 """ |
347 __regid__ = 'tsearch' |
347 __regid__ = 'tsearch' |
348 |
348 |
349 def cell_call(self, row, col, **kwargs): |
349 def cell_call(self, row, col, **kwargs): |
350 entity = self.complete_entity(row, col) |
350 entity = self.cw_rset.complete_entity(row, col) |
351 self.w(entity.view('incontext')) |
351 self.w(entity.view('incontext')) |
352 searched = self.rset.searched_text() |
352 searched = self.cw_rset.searched_text() |
353 if searched is None: |
353 if searched is None: |
354 return |
354 return |
355 searched = searched.lower() |
355 searched = searched.lower() |
356 highlighted = '<b>%s</b>' % searched |
356 highlighted = '<b>%s</b>' % searched |
357 for attr in entity.e_schema.indexable_attributes(): |
357 for attr in entity.e_schema.indexable_attributes(): |