60 from logilab.common.compat import any |
60 from logilab.common.compat import any |
61 |
61 |
62 from cubicweb import neg_role |
62 from cubicweb import neg_role |
63 from cubicweb.rtags import (RelationTags, RelationTagsBool, RelationTagsSet, |
63 from cubicweb.rtags import (RelationTags, RelationTagsBool, RelationTagsSet, |
64 RelationTagsDict, NoTargetRelationTagsDict, |
64 RelationTagsDict, NoTargetRelationTagsDict, |
65 register_rtag, _ensure_str_key) |
65 _ensure_str_key) |
66 from cubicweb.schema import META_RTYPES, INTERNAL_TYPES, WORKFLOW_TYPES |
66 from cubicweb.schema import META_RTYPES, INTERNAL_TYPES, WORKFLOW_TYPES |
67 |
67 |
68 |
68 |
69 # primary view configuration ################################################## |
69 # primary view configuration ################################################## |
70 |
70 |
71 def init_primaryview_section(rtag, sschema, rschema, oschema, role): |
71 class PrimaryViewSectionRelationTags(RelationTags): |
72 if rtag.get(sschema, rschema, oschema, role) is None: |
72 """primary view section configuration""" |
73 rdef = rschema.rdef(sschema, oschema) |
73 __regid__ = 'primaryview_section' |
74 if rschema.final: |
74 |
75 if rschema.meta or sschema.is_metadata(rschema) \ |
75 _allowed_values = frozenset(('attributes', 'relations', |
76 or oschema.type in ('Password', 'Bytes'): |
76 'sideboxes', 'hidden')) |
77 section = 'hidden' |
77 |
|
78 def _init(self, sschema, rschema, oschema, role): |
|
79 if self.get(sschema, rschema, oschema, role) is None: |
|
80 rdef = rschema.rdef(sschema, oschema) |
|
81 if rschema.final: |
|
82 if rschema.meta or sschema.is_metadata(rschema) \ |
|
83 or oschema.type in ('Password', 'Bytes'): |
|
84 section = 'hidden' |
|
85 else: |
|
86 section = 'attributes' |
78 else: |
87 else: |
79 section = 'attributes' |
88 if rdef.role_cardinality(role) in '1+': |
80 else: |
89 section = 'attributes' |
81 if rdef.role_cardinality(role) in '1+': |
90 elif rdef.composite == neg_role(role): |
82 section = 'attributes' |
91 section = 'relations' |
83 elif rdef.composite == neg_role(role): |
92 else: |
84 section = 'relations' |
93 section = 'sideboxes' |
85 else: |
94 self.tag_relation((sschema, rschema, oschema, role), section) |
86 section = 'sideboxes' |
95 |
87 rtag.tag_relation((sschema, rschema, oschema, role), section) |
96 primaryview_section = PrimaryViewSectionRelationTags() |
88 |
|
89 primaryview_section = RelationTags('primaryview_section', |
|
90 init_primaryview_section, |
|
91 frozenset(('attributes', 'relations', |
|
92 'sideboxes', 'hidden'))) |
|
93 |
97 |
94 |
98 |
95 class DisplayCtrlRelationTags(NoTargetRelationTagsDict): |
99 class DisplayCtrlRelationTags(NoTargetRelationTagsDict): |
|
100 """primary view display controller configuration""" |
|
101 __regid__ = 'primaryview_display_ctrl' |
|
102 |
96 def __init__(self, *args, **kwargs): |
103 def __init__(self, *args, **kwargs): |
97 super(DisplayCtrlRelationTags, self).__init__(*args, **kwargs) |
104 super(DisplayCtrlRelationTags, self).__init__(*args, **kwargs) |
98 self.counter = 0 |
105 self.counter = 0 |
99 |
106 |
100 def init_primaryview_display_ctrl(rtag, sschema, rschema, oschema, role): |
107 def _init(self, sschema, rschema, oschema, role): |
101 if role == 'subject': |
108 if role == 'subject': |
102 oschema = '*' |
109 oschema = '*' |
103 else: |
110 else: |
104 sschema = '*' |
111 sschema = '*' |
105 rtag.counter += 1 |
112 self.counter += 1 |
106 rtag.setdefault((sschema, rschema, oschema, role), 'order', rtag.counter) |
113 self.setdefault((sschema, rschema, oschema, role), |
107 |
114 'order', |
108 primaryview_display_ctrl = DisplayCtrlRelationTags('primaryview_display_ctrl', |
115 self.counter) |
109 init_primaryview_display_ctrl) |
116 |
|
117 primaryview_display_ctrl = DisplayCtrlRelationTags() |
110 |
118 |
111 |
119 |
112 # index view configuration #################################################### |
120 # index view configuration #################################################### |
113 # entity type section in the index/manage page. May be one of |
121 # entity type section in the index/manage page. May be one of |
114 # * 'application' |
122 # * 'application' |
115 # * 'system' |
123 # * 'system' |
116 # * 'schema' |
124 # * 'schema' |
117 # * 'hidden' |
125 # * 'hidden' |
118 # * 'subobject' (not displayed by default) |
126 # * 'subobject' (not displayed by default) |
119 |
127 |
120 class InitializableDict(dict): |
128 class InitializableDict(dict): # XXX not a rtag. Turn into an appobject? |
121 def __init__(self, *args, **kwargs): |
129 def __init__(self, *args, **kwargs): |
122 super(InitializableDict, self).__init__(*args, **kwargs) |
130 super(InitializableDict, self).__init__(*args, **kwargs) |
123 register_rtag(self) |
|
124 self.__defaults = dict(self) |
131 self.__defaults = dict(self) |
125 |
132 |
126 def init(self, schema, check=True): |
133 def init(self, schema, check=True): |
127 self.update(self.__defaults) |
134 self.update(self.__defaults) |
128 for eschema in schema.entities(): |
135 for eschema in schema.entities(): |
163 composed = not rschema.final and rdef.composite == 'subject' |
171 composed = not rschema.final and rdef.composite == 'subject' |
164 return card, composed |
172 return card, composed |
165 |
173 |
166 class AutoformSectionRelationTags(RelationTagsSet): |
174 class AutoformSectionRelationTags(RelationTagsSet): |
167 """autoform relations'section""" |
175 """autoform relations'section""" |
|
176 __regid__ = 'autoform_section' |
168 |
177 |
169 _allowed_form_types = ('main', 'inlined', 'muledit') |
178 _allowed_form_types = ('main', 'inlined', 'muledit') |
170 _allowed_values = {'main': ('attributes', 'inlined', 'relations', |
179 _allowed_values = {'main': ('attributes', 'inlined', 'relations', |
171 'metadata', 'hidden'), |
180 'metadata', 'hidden'), |
172 'inlined': ('attributes', 'inlined', 'hidden'), |
181 'inlined': ('attributes', 'inlined', 'hidden'), |
175 |
184 |
176 def init(self, schema, check=True): |
185 def init(self, schema, check=True): |
177 super(AutoformSectionRelationTags, self).init(schema, check) |
186 super(AutoformSectionRelationTags, self).init(schema, check) |
178 self.apply(schema, self._initfunc_step2) |
187 self.apply(schema, self._initfunc_step2) |
179 |
188 |
180 @staticmethod |
189 def _init(self, sschema, rschema, oschema, role): |
181 def _initfunc(self, sschema, rschema, oschema, role): |
|
182 formsections = self.init_get(sschema, rschema, oschema, role) |
190 formsections = self.init_get(sschema, rschema, oschema, role) |
183 if formsections is None: |
191 if formsections is None: |
184 formsections = self.tag_container_cls() |
192 formsections = self.tag_container_cls() |
185 if not any(tag.startswith('inlined') for tag in formsections): |
193 if not any(tag.startswith('inlined') for tag in formsections): |
186 if not rschema.final: |
194 if not rschema.final: |
188 if 'main_inlined' in negsects: |
196 if 'main_inlined' in negsects: |
189 formsections.add('inlined_hidden') |
197 formsections.add('inlined_hidden') |
190 key = _ensure_str_key( (sschema, rschema, oschema, role) ) |
198 key = _ensure_str_key( (sschema, rschema, oschema, role) ) |
191 self._tagdefs[key] = formsections |
199 self._tagdefs[key] = formsections |
192 |
200 |
193 @staticmethod |
|
194 def _initfunc_step2(self, sschema, rschema, oschema, role): |
201 def _initfunc_step2(self, sschema, rschema, oschema, role): |
195 formsections = self.get(sschema, rschema, oschema, role) |
202 formsections = self.get(sschema, rschema, oschema, role) |
196 sectdict = _formsections_as_dict(formsections) |
203 sectdict = _formsections_as_dict(formsections) |
197 if rschema in META_RTYPES: |
204 if rschema in META_RTYPES: |
198 sectdict.setdefault('main', 'hidden') |
205 sectdict.setdefault('main', 'hidden') |
345 and not rdef.has_perm(cw, 'delete', toeid=eid, |
352 and not rdef.has_perm(cw, 'delete', toeid=eid, |
346 fromeid=entity.related(rschema.type, role)[0][0])): |
353 fromeid=entity.related(rschema.type, role)[0][0])): |
347 continue |
354 continue |
348 yield (rschema, targetschemas, role) |
355 yield (rschema, targetschemas, role) |
349 |
356 |
350 autoform_section = AutoformSectionRelationTags('autoform_section') |
357 autoform_section = AutoformSectionRelationTags() |
351 |
358 |
352 # relations'field class |
359 # relations'field class |
353 autoform_field = RelationTags('autoform_field') |
360 class AutoformFieldTags(RelationTags): |
|
361 __regid__ = 'autoform_field' |
|
362 |
|
363 autoform_field = AutoformFieldTags() |
354 |
364 |
355 # relations'field explicit kwargs (given to field's __init__) |
365 # relations'field explicit kwargs (given to field's __init__) |
356 autoform_field_kwargs = RelationTagsDict('autoform_field_kwargs') |
366 class AutoformFieldKwargsTags(RelationTagsDict): |
|
367 __regid__ = 'autoform_field_kwargs' |
|
368 |
|
369 autoform_field_kwargs = AutoformFieldKwargsTags() |
357 |
370 |
358 |
371 |
359 # set of tags of the form <action>_on_new on relations. <action> is a |
372 # set of tags of the form <action>_on_new on relations. <action> is a |
360 # schema action (add/update/delete/read), and when such a tag is found |
373 # schema action (add/update/delete/read), and when such a tag is found |
361 # permissions checking is by-passed and supposed to be ok |
374 # permissions checking is by-passed and supposed to be ok |
362 autoform_permissions_overrides = RelationTagsSet('autoform_permissions_overrides') |
375 class AutoFormPermissionsOverrides(RelationTagsSet): |
|
376 __regid__ = 'autoform_permissions_overrides' |
|
377 |
|
378 autoform_permissions_overrides = AutoFormPermissionsOverrides() |
|
379 |
363 |
380 |
364 class ReleditTags(NoTargetRelationTagsDict): |
381 class ReleditTags(NoTargetRelationTagsDict): |
365 """Associate to relation a dictionary to control `reledit` (e.g. edition of |
382 """Associate to relation a dictionary to control `reledit` (e.g. edition of |
366 attributes / relations from within views). |
383 attributes / relations from within views). |
367 |
384 |
386 (to edit the related entity). This controls whether to edit the relation |
403 (to edit the related entity). This controls whether to edit the relation |
387 or the target entity of the relation. Currently only one-to-one relations |
404 or the target entity of the relation. Currently only one-to-one relations |
388 support target entity edition. By default, the 'related' option is taken |
405 support target entity edition. By default, the 'related' option is taken |
389 whenever the relation is composite. |
406 whenever the relation is composite. |
390 """ |
407 """ |
|
408 __regid__ = 'reledit' |
391 _keys = frozenset('novalue_label novalue_include_rtype reload rvid edit_target'.split()) |
409 _keys = frozenset('novalue_label novalue_include_rtype reload rvid edit_target'.split()) |
392 |
410 |
393 def tag_relation(self, key, tag): |
411 def tag_relation(self, key, tag): |
394 for tagkey in tag.iterkeys(): |
412 for tagkey in tag.iterkeys(): |
395 assert tagkey in self._keys, 'tag %r not in accepted tags: %r' % (tag, self._keys) |
413 assert tagkey in self._keys, 'tag %r not in accepted tags: %r' % (tag, self._keys) |
396 return super(ReleditTags, self).tag_relation(key, tag) |
414 return super(ReleditTags, self).tag_relation(key, tag) |
397 |
415 |
398 def init_reledit_ctrl(rtag, sschema, rschema, oschema, role): |
416 def _init(self, sschema, rschema, oschema, role): |
399 values = rtag.get(sschema, rschema, oschema, role) |
417 values = self.get(sschema, rschema, oschema, role) |
400 if not rschema.final: |
418 if not rschema.final: |
401 composite = rschema.rdef(sschema, oschema).composite == role |
419 composite = rschema.rdef(sschema, oschema).composite == role |
402 if role == 'subject': |
420 if role == 'subject': |
403 oschema = '*' |
421 oschema = '*' |
404 else: |
422 else: |
405 sschema = '*' |
423 sschema = '*' |
406 edittarget = values.get('edit_target') |
424 edittarget = values.get('edit_target') |
407 if edittarget not in (None, 'rtype', 'related'): |
425 if edittarget not in (None, 'rtype', 'related'): |
408 rtag.warning('reledit: wrong value for edit_target on relation %s: %s', |
426 self.warning('reledit: wrong value for edit_target on relation %s: %s', |
409 rschema, edittarget) |
427 rschema, edittarget) |
410 edittarget = None |
428 edittarget = None |
411 if not edittarget: |
429 if not edittarget: |
412 edittarget = 'related' if composite else 'rtype' |
430 edittarget = 'related' if composite else 'rtype' |
413 rtag.tag_relation((sschema, rschema, oschema, role), |
431 self.tag_relation((sschema, rschema, oschema, role), |
414 {'edit_target': edittarget}) |
432 {'edit_target': edittarget}) |
415 if not 'novalue_include_rtype' in values: |
433 if not 'novalue_include_rtype' in values: |
416 showlabel = primaryview_display_ctrl.get( |
434 showlabel = primaryview_display_ctrl.get( |
417 sschema, rschema, oschema, role).get('showlabel', True) |
435 sschema, rschema, oschema, role).get('showlabel', True) |
418 rtag.tag_relation((sschema, rschema, oschema, role), |
436 self.tag_relation((sschema, rschema, oschema, role), |
419 {'novalue_include_rtype': not showlabel}) |
437 {'novalue_include_rtype': not showlabel}) |
420 |
438 |
421 reledit_ctrl = ReleditTags('reledit', init_reledit_ctrl) |
439 reledit_ctrl = ReleditTags() |
|
440 |
422 |
441 |
423 # boxes.EditBox configuration ################################################# |
442 # boxes.EditBox configuration ################################################# |
424 |
443 |
425 # 'link' / 'create' relation tags, used to control the "add entity" submenu |
444 # 'link' / 'create' relation tags, used to control the "add entity" submenu |
426 def init_actionbox_appearsin_addmenu(rtag, sschema, rschema, oschema, role): |
445 class ActionBoxUicfg(RelationTagsBool): |
427 if rtag.get(sschema, rschema, oschema, role) is None: |
446 __regid__ = 'actionbox_appearsin_addmenu' |
428 if rschema in META_RTYPES: |
447 |
429 rtag.tag_relation((sschema, rschema, oschema, role), False) |
448 def _init(self, sschema, rschema, oschema, role): |
430 return |
449 if self.get(sschema, rschema, oschema, role) is None: |
431 rdef = rschema.rdef(sschema, oschema) |
450 if rschema in META_RTYPES: |
432 if not rdef.role_cardinality(role) in '?1' and rdef.composite == role: |
451 self.tag_relation((sschema, rschema, oschema, role), False) |
433 rtag.tag_relation((sschema, rschema, oschema, role), True) |
452 return |
434 |
453 rdef = rschema.rdef(sschema, oschema) |
435 actionbox_appearsin_addmenu = RelationTagsBool('actionbox_appearsin_addmenu', |
454 if not rdef.role_cardinality(role) in '?1' and rdef.composite == role: |
436 init_actionbox_appearsin_addmenu) |
455 self.tag_relation((sschema, rschema, oschema, role), True) |
|
456 |
|
457 actionbox_appearsin_addmenu = ActionBoxUicfg() |
|
458 |
|
459 |
|
460 |
|
461 def registration_callback(vreg): |
|
462 vreg.register_all(globals().values(), __name__) |
|
463 indexview_etype_section.init(vreg.schema) |