3 :organization: Logilab |
3 :organization: Logilab |
4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
4 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved. |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
5 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr |
6 """ |
6 """ |
7 __docformat__ = "restructuredtext en" |
7 __docformat__ = "restructuredtext en" |
|
8 _ = unicode |
8 |
9 |
9 from warnings import warn |
10 from warnings import warn |
10 |
11 |
11 from logilab.mtconverter import html_escape |
12 from logilab.mtconverter import html_escape |
12 |
13 |
13 from cubicweb import Unauthorized |
14 from cubicweb import Unauthorized |
14 from cubicweb.view import EntityView |
15 from cubicweb.view import EntityView |
15 from cubicweb.web.uicfg import rdisplay |
16 from cubicweb.web import uicfg |
16 |
17 |
17 _ = unicode |
|
18 |
18 |
19 |
19 |
20 class PrimaryView(EntityView): |
20 class PrimaryView(EntityView): |
21 """the full view of an non final entity""" |
21 """the full view of an non final entity""" |
22 id = 'primary' |
22 id = 'primary' |
23 title = _('primary') |
23 title = _('primary') |
24 show_attr_label = True |
24 show_attr_label = True |
25 show_rel_label = True |
25 show_rel_label = True |
26 skip_none = True |
26 skip_none = True |
27 rdisplay = rdisplay |
27 rsection = uicfg.primaryview_section |
|
28 display_ctrl = uicfg.primaryview_display_ctrl |
28 main_related_section = True |
29 main_related_section = True |
29 |
30 |
30 @classmethod |
31 @classmethod |
31 def vreg_initialization_completed(cls): |
32 def vreg_initialization_completed(cls): |
32 """set default category tags for relations where it's not yet defined in |
33 """set default category tags for relations where it's not yet defined in |
33 the category relation tags |
34 the category relation tags |
34 """ |
35 """ |
35 for eschema in cls.schema.entities(): |
36 cls.rsection.init(cls.schema) |
36 for rschema, tschemas, role in eschema.relation_definitions(True): |
37 cls.display_ctrl.init(cls.schema) |
37 for tschema in tschemas: |
|
38 if role == 'subject': |
|
39 X, Y = eschema, tschema |
|
40 card = rschema.rproperty(X, Y, 'cardinality')[0] |
|
41 composed = rschema.rproperty(X, Y, 'composite') == 'object' |
|
42 else: |
|
43 X, Y = tschema, eschema |
|
44 card = rschema.rproperty(X, Y, 'cardinality')[1] |
|
45 composed = rschema.rproperty(X, Y, 'composite') == 'subject' |
|
46 displayinfo = cls.rdisplay.get(X, rschema, Y, role) |
|
47 if displayinfo is None: |
|
48 if rschema.is_final(): |
|
49 if rschema.meta or tschema.type in ('Password', 'Bytes'): |
|
50 where = None |
|
51 else: |
|
52 where = 'attributes' |
|
53 elif card in '1+': |
|
54 where = 'attributes' |
|
55 elif composed: |
|
56 where = 'relations' |
|
57 else: |
|
58 where = 'sideboxes' |
|
59 displayinfo = {'where': where, |
|
60 'order': cls.rdisplay.get_timestamp()} |
|
61 cls.rdisplay.tag_relation(X, rschema, Y, displayinfo, |
|
62 tagged=role) |
|
63 if role == 'subject': |
|
64 displayinfo.setdefault('label', rschema.type) |
|
65 else: |
|
66 displayinfo.setdefault('label', '%s_%s' % (rschema, role)) |
|
67 |
38 |
68 def html_headers(self): |
39 def html_headers(self): |
69 """return a list of html headers (eg something to be inserted between |
40 """return a list of html headers (eg something to be inserted between |
70 <head> and </head> of the returned page |
41 <head> and </head> of the returned page |
71 |
42 |
148 def summary(self, entity): |
119 def summary(self, entity): |
149 """default implementation return an empty string""" |
120 """default implementation return an empty string""" |
150 return u'' |
121 return u'' |
151 |
122 |
152 def render_entity_attributes(self, entity, siderelations=None): |
123 def render_entity_attributes(self, entity, siderelations=None): |
153 for rschema, tschemas, role, displayinfo in self._iter_display(entity, 'attributes'): |
124 for rschema, tschemas, role, dispctrl in self._section_def(entity, 'attributes'): |
154 vid = displayinfo.get('vid', 'reledit') |
125 vid = dispctrl.get('vid', 'reledit') |
155 if rschema.is_final() or vid == 'reledit': |
126 if rschema.is_final() or vid == 'reledit': |
156 value = entity.view(vid, rtype=rschema.type, role=role) |
127 value = entity.view(vid, rtype=rschema.type, role=role) |
157 else: |
128 else: |
158 rset = self._relation_rset(entity, rschema, role, displayinfo) |
129 rset = self._relation_rset(entity, rschema, role, dispctrl) |
159 if rset: |
130 if rset: |
160 value = self.view(vid, rset) |
131 value = self.view(vid, rset) |
161 else: |
132 else: |
162 value = None |
133 value = None |
163 if self.skip_none and (value is None or value == ''): |
134 if self.skip_none and (value is None or value == ''): |
164 continue |
135 continue |
165 self._render_attribute(rschema, value) |
136 self._render_attribute(rschema, value) |
166 |
137 |
167 def render_entity_relations(self, entity, siderelations=None): |
138 def render_entity_relations(self, entity, siderelations=None): |
168 for rschema, tschemas, role, displayinfo in self._iter_display(entity, 'relations'): |
139 for rschema, tschemas, role, dispctrl in self._section_def(entity, 'relations'): |
169 rset = self._relation_rset(entity, rschema, role, displayinfo) |
140 rset = self._relation_rset(entity, rschema, role, dispctrl) |
170 if rset: |
141 if rset: |
171 self._render_relation(rset, displayinfo, 'autolimited', |
142 self._render_relation(rset, dispctrl, 'autolimited', |
172 self.show_rel_label) |
143 self.show_rel_label) |
173 |
144 |
174 def render_side_boxes(self, boxes): |
145 def render_side_boxes(self, boxes): |
175 """display side related relations: |
146 """display side related relations: |
176 non-meta in a first step, meta in a second step |
147 non-meta in a first step, meta in a second step |
177 """ |
148 """ |
178 for box in boxes: |
149 for box in boxes: |
179 if isinstance(box, tuple): |
150 if isinstance(box, tuple): |
180 label, rset, vid, _ = box |
151 label, rset, vid = box |
181 self.w(u'<div class="sideRelated">') |
152 self.w(u'<div class="sideRelated">') |
182 self.wview(vid, rset, title=label) |
153 self.wview(vid, rset, title=label) |
183 self.w(u'</div>') |
154 self.w(u'</div>') |
184 else: |
155 else: |
185 try: |
156 try: |
189 # .call() and not cell_call() |
160 # .call() and not cell_call() |
190 box.render(w=self.w) |
161 box.render(w=self.w) |
191 |
162 |
192 def _prepare_side_boxes(self, entity): |
163 def _prepare_side_boxes(self, entity): |
193 sideboxes = [] |
164 sideboxes = [] |
194 for rschema, tschemas, role, displayinfo in self._iter_display(entity, 'sideboxes'): |
165 for rschema, tschemas, role, dispctrl in self._section_def(entity, 'sideboxes'): |
195 rset = self._relation_rset(entity, rschema, role, displayinfo) |
166 rset = self._relation_rset(entity, rschema, role, dispctrl) |
196 if not rset: |
167 if not rset: |
197 continue |
168 continue |
198 label = display_name(self.req, rschema.type, role) |
169 label = display_name(self.req, rschema.type, role) |
199 vid = displayinfo.get('vid', 'autolimited') |
170 vid = dispctrl.get('vid', 'sidebox') |
200 sideboxes.append((label, rset, vid, displayinfo.get('order'))) |
171 sideboxes.append( (label, rset, vid) ) |
201 sideboxes = sorted(sideboxes, key=lambda x: x[-1]) |
172 sideboxes += self.vreg.possible_vobjects('boxes', self.req, self.rset, |
202 sideboxes += list(self.vreg.possible_vobjects('boxes', self.req, self.rset, |
173 row=self.row, view=self, |
203 row=self.row, view=self, |
174 context='incontext') |
204 context='incontext')) |
|
205 return sideboxes |
175 return sideboxes |
206 |
176 |
207 def _iter_display(self, entity, where): |
177 def _section_def(self, entity, where): |
|
178 rdefs = [] |
208 eschema = entity.e_schema |
179 eschema = entity.e_schema |
209 for rschema, tschemas, role in eschema.relation_definitions(True): |
180 for rschema, tschemas, role in eschema.relation_definitions(True): |
210 matchtschemas = [] |
181 matchtschemas = [] |
211 for tschema in tschemas: |
182 for tschema in tschemas: |
212 displayinfo = self.rdisplay.etype_get(eschema, rschema, role, |
183 section = self.rsection.etype_get(eschema, rschema, role, |
213 tschema) |
184 tschema) |
214 assert displayinfo is not None, (str(rschema), role, |
185 if section == where: |
215 str(eschema), str(tschema)) |
|
216 if displayinfo.get('where') == where: |
|
217 matchtschemas.append(tschema) |
186 matchtschemas.append(tschema) |
218 if matchtschemas: |
187 if matchtschemas: |
219 # XXX pick the latest displayinfo |
188 # XXX pick the latest dispctrl |
220 yield rschema, matchtschemas, role, displayinfo |
189 dispctrl = self.display_ctrl.etype_get(eschema, rschema, role, |
221 |
190 matchtschemas[-1]) |
222 def _relation_rset(self, entity, rschema, role, displayinfo): |
191 |
|
192 rdefs.append( (rschema, matchtschemas, role, dispctrl) ) |
|
193 return sorted(rdefs, key=lambda x: x[-1]['order']) |
|
194 |
|
195 def _relation_rset(self, entity, rschema, role, dispctrl): |
223 try: |
196 try: |
224 if displayinfo.get('limit'): |
197 if dispctrl.get('limit'): |
225 rset = entity.related(rschema.type, role, |
198 rset = entity.related(rschema.type, role, |
226 limit=self.maxrelated+1) |
199 limit=self.maxrelated+1) |
227 else: |
200 else: |
228 rset = entity.related(rschema.type, role) |
201 rset = entity.related(rschema.type, role) |
229 except Unauthorized: |
202 except Unauthorized: |
230 return |
203 return |
231 if 'filter' in displayinfo: |
204 if 'filter' in dispctrl: |
232 rset = displayinfo['filter'](rset) |
205 rset = dispctrl['filter'](rset) |
233 return rset |
206 return rset |
234 |
207 |
235 def _render_relation(self, rset, displayinfo, defaultvid, showlabel): |
208 def _render_relation(self, rset, dispctrl, defaultvid, showlabel): |
236 self.w(u'<div class="section">') |
209 self.w(u'<div class="section">') |
237 if showlabel: |
210 if showlabel: |
238 self.w(u'<h4>%s</h4>' % self.req._(displayinfo['label'])) |
211 self.w(u'<h4>%s</h4>' % self.req._(dispctrl['label'])) |
239 self.wview(displayinfo.get('vid', defaultvid), rset) |
212 self.wview(dispctrl.get('vid', defaultvid), rset) |
240 self.w(u'</div>') |
213 self.w(u'</div>') |
241 |
214 |
242 def _render_attribute(self, rschema, value, role='subject'): |
215 def _render_attribute(self, rschema, value, role='subject'): |
243 if rschema.is_final(): |
216 if rschema.is_final(): |
244 show_label = self.show_attr_label |
217 show_label = self.show_attr_label |