diff -r e2ed81c20e74 -r 35cd057339b2 web/views/autoform.py --- a/web/views/autoform.py Wed Jan 20 08:43:41 2010 +0100 +++ b/web/views/autoform.py Wed Jan 20 10:06:12 2010 +0100 @@ -9,12 +9,12 @@ __docformat__ = "restructuredtext en" _ = unicode -from logilab.common.decorators import cached +from logilab.common.decorators import cached, iclassmethod from cubicweb import typed_eid from cubicweb.web import stdmsgs, uicfg from cubicweb.web import form, formwidgets as fwdgs -from cubicweb.web.views import forms, editforms +from cubicweb.web.views import forms, editforms, editviews _afs = uicfg.autoform_section @@ -44,6 +44,31 @@ # which relations should be edited display_fields = None + def _generic_relations_field(self): + try: + srels_by_cat = self.srelations_by_category('generic', 'add', strict=True) + warn('[3.6] %s: srelations_by_category is deprecated, use uicfg or ' + 'override editable_relations instead' % classid(form), + DeprecationWarning) + except AttributeError: + srels_by_cat = self.editable_relations() + if not srels_by_cat: + raise form.FieldNotFound('_cw_generic_field') + return editviews.GenericRelationsField(self.editable_relations()) + + @iclassmethod + def field_by_name(cls_or_self, name, role=None, eschema=None): + """return field with the given name and role. If field is not explicitly + defined for the form but `eclass` is specified, guess_field will be + called. + """ + try: + return super(AutomaticEntityForm, cls_or_self).field_by_name(name, role, eschema) + except form.FieldNotFound: + if name == '_cw_generic_field' and not isinstance(cls_or_self, type): + return cls_or_self._generic_relations_field() + raise + # base automatic entity form methods ####################################### def __init__(self, *args, **kwargs): @@ -64,6 +89,12 @@ except form.FieldNotFound: # meta attribute such as _format continue + if self.formtype == 'main' and entity.has_eid(): + try: + self.fields.append(self.field_by_name('_cw_generic_field')) + except form.FieldNotFound: + # no editable relation + pass self.maxrelitems = self._cw.property_value('navigation.related-limit') self.force_display = bool(self._cw.form.get('__force_display')) fnum = len(self.fields) @@ -163,63 +194,6 @@ # generic relations modifier ############################################### - def relations_table(self): - """yiels 3-tuples (rtype, target, related_list) - where itself a list of : - - node_id (will be the entity element's DOM id) - - appropriate javascript's togglePendingDelete() function call - - status 'pendingdelete' or '' - - oneline view of related entity - """ - entity = self.edited_entity - pending_deletes = self._cw.get_pending_deletes(entity.eid) - for label, rschema, role in self.editable_relations(): - relatedrset = entity.related(rschema, role, limit=self.related_limit) - if rschema.has_perm(self._cw, 'delete'): - toggleable_rel_link_func = editforms.toggleable_relation_link - else: - toggleable_rel_link_func = lambda x, y, z: u'' - related = [] - for row in xrange(relatedrset.rowcount): - nodeid = editforms.relation_id(entity.eid, rschema, role, - relatedrset[row][0]) - if nodeid in pending_deletes: - status = u'pendingDelete' - label = '+' - else: - status = u'' - label = 'x' - dellink = toggleable_rel_link_func(entity.eid, nodeid, label) - eview = self._cw.view('oneline', relatedrset, row=row) - related.append((nodeid, dellink, status, eview)) - yield (rschema, role, related) - - def restore_pending_inserts(self, cell=False): - """used to restore edition page as it was before clicking on - 'search for ' - """ - eid = self.edited_entity.eid - cell = cell and "div_insert_" or "tr" - pending_inserts = set(self._cw.get_pending_inserts(eid)) - for pendingid in pending_inserts: - eidfrom, rtype, eidto = pendingid.split(':') - if typed_eid(eidfrom) == eid: # subject - label = display_name(self._cw, rtype, 'subject', - self.edited_entity.__regid__) - reid = eidto - else: - label = display_name(self._cw, rtype, 'object', - self.edited_entity.__regid__) - reid = eidfrom - jscall = "javascript: cancelPendingInsert('%s', '%s', null, %s);" \ - % (pendingid, cell, eid) - rset = self._cw.eid_rset(reid) - eview = self._cw.view('text', rset, row=0) - # XXX find a clean way to handle baskets - if rset.description[0][0] == 'Basket': - eview = '%s (%s)' % (eview, display_name(self._cw, 'Basket')) - yield rtype, pendingid, jscall, label, reid, eview - # inlined forms support #################################################### @cached