# HG changeset patch # User Sylvain Thénault # Date 1275909744 -7200 # Node ID 0f2ded880d014367d309dfe1d2a99d72b2ddad72 # Parent aa04ccb8dd623ad3f5e0298f0bb5aa22617958d0# Parent 0a8bb754fe51036517457eda3372f3a1039b9b81 backport stable diff -r aa04ccb8dd62 -r 0f2ded880d01 .hgtags --- a/.hgtags Mon Jun 07 12:39:15 2010 +0200 +++ b/.hgtags Mon Jun 07 13:22:24 2010 +0200 @@ -127,3 +127,5 @@ eb972d125eefd0de2d0743e95c6e1f4e3e93e4c1 cubicweb-debian-version-3.8.1-1 ef2e37d34013488a2018e73338fbbfbde5901c5c cubicweb-version-3.8.2 2b962bb9eee8ee7156a12cf137428c292f8e3b35 cubicweb-debian-version-3.8.2-1 +7e6c6a2a272d0a95fd42248f3125e45185f0eef1 cubicweb-version-3.8.3 +1ccaa924786047be66b44f6dbc76e6631f56b04a cubicweb-debian-version-3.8.3-1 diff -r aa04ccb8dd62 -r 0f2ded880d01 debian/changelog --- a/debian/changelog Mon Jun 07 12:39:15 2010 +0200 +++ b/debian/changelog Mon Jun 07 13:22:24 2010 +0200 @@ -1,3 +1,9 @@ +cubicweb (3.8.3-1) unstable; urgency=low + + * new upstream release + + -- Sylvain Thénault Mon, 07 Jun 2010 09:19:50 +0200 + cubicweb (3.8.2-1) unstable; urgency=low * new upstream release @@ -56,7 +62,7 @@ -- Sylvain Thénault Tue, 16 Mar 2010 17:55:37 +0100 - cubicweb (3.6.3-1) unstable; urgency=low +cubicweb (3.6.3-1) unstable; urgency=low * remove postgresql-contrib from cubicweb dependency (using tsearch which is included with postgres >= 8.3) diff -r aa04ccb8dd62 -r 0f2ded880d01 etwist/server.py --- a/etwist/server.py Mon Jun 07 12:39:15 2010 +0200 +++ b/etwist/server.py Mon Jun 07 13:22:24 2010 +0200 @@ -42,7 +42,6 @@ from cubicweb.web import dumps from logilab.common.decorators import monkeypatch -from logilab.common.daemon import daemonize from cubicweb import AuthenticationError, ConfigurationError, CW_EVENT_MANAGER from cubicweb.web import Redirect, DirectResponse, StatusResponse, LogOut @@ -398,12 +397,11 @@ # serve it via standard HTTP on port set in the configuration port = config['port'] or 8080 reactor.listenTCP(port, website) - logger = getLogger('cubicweb.twisted') if not config.debugmode: if sys.platform == 'win32': raise ConfigurationError("Under windows, you must use the service management " "commands (e.g : 'net start my_instance)'") - logger.info('instance started in the background on %s', root_resource.base_url) + LOGGER.info('instance started in the background on %s', root_resource.base_url) if daemonize(config['pid-file']): return # child process root_resource.init_publisher() # before changing uid @@ -415,7 +413,7 @@ uid = getpwnam(config['uid']).pw_uid os.setuid(uid) root_resource.start_service() - logger.info('instance started on %s', root_resource.base_url) + LOGGER.info('instance started on %s', root_resource.base_url) # avoid annoying warnign if not in Main Thread signals = threading.currentThread().getName() == 'MainThread' if config['profile']: diff -r aa04ccb8dd62 -r 0f2ded880d01 hooks/security.py --- a/hooks/security.py Mon Jun 07 12:39:15 2010 +0200 +++ b/hooks/security.py Mon Jun 07 13:22:24 2010 +0200 @@ -25,7 +25,7 @@ from cubicweb.server import BEFORE_ADD_RELATIONS, ON_COMMIT_ADD_RELATIONS, hook -def check_entity_attributes(session, entity, editedattrs=None): +def check_entity_attributes(session, entity, editedattrs=None, creation=False): eid = entity.eid eschema = entity.e_schema # ._cw_skip_security_attributes is there to bypass security for attributes @@ -42,6 +42,8 @@ rdef = eschema.rdef(attr) if rdef.final: # non final relation are checked by other hooks # add/delete should be equivalent (XXX: unify them into 'update' ?) + if creation and not rdef.permissions.get('update'): + continue rdef.check_perm(session, 'update', eid=eid) # don't update dontcheck until everything went fine: see usage in # after_update_entity, where if we got an Unauthorized at hook time, we will @@ -58,6 +60,7 @@ action = values[1] entity.cw_check_perm(action) check_entity_attributes(session, entity, values[2:]) + creation=self.creation) def commit_event(self): pass @@ -94,7 +97,7 @@ def __call__(self): hook.set_operation(self._cw, 'check_entity_perm_op', (self.entity.eid, 'add') + tuple(self.entity.edited_attributes), - _CheckEntityPermissionOp) + _CheckEntityPermissionOp, creation=True) class AfterUpdateEntitySecurityHook(SecurityHook): @@ -113,7 +116,7 @@ # overwritten hook.set_operation(self._cw, 'check_entity_perm_op', (self.entity.eid, 'update') + tuple(self.entity.edited_attributes), - _CheckEntityPermissionOp) + _CheckEntityPermissionOp, creation=False) class BeforeDelEntitySecurityHook(SecurityHook): diff -r aa04ccb8dd62 -r 0f2ded880d01 i18n/en.po --- a/i18n/en.po Mon Jun 07 12:39:15 2010 +0200 +++ b/i18n/en.po Mon Jun 07 13:22:24 2010 +0200 @@ -31,7 +31,7 @@ msgstr "" msgid " :" -msgstr "" +msgstr ":" #, python-format msgid "%(attr)s set to %(newvalue)s" @@ -172,14 +172,15 @@ msgstr "1 0..1" #, python-format +msgid "<%s not specified>" +msgstr "" + +#, python-format msgid "" "
This schema of the data model excludes the meta-data, but you " "can also display a complete schema with meta-data.
" msgstr "" -msgid "" -msgstr "" - msgid "?*" msgstr "0..1 0..n" @@ -2599,6 +2600,9 @@ msgid "log in" msgstr "" +msgid "log out first" +msgstr "" + msgid "login" msgstr "" @@ -3947,6 +3951,3 @@ msgid "you should probably delete that property" msgstr "" - -#~ msgid "schema-image" -#~ msgstr "image" diff -r aa04ccb8dd62 -r 0f2ded880d01 i18n/es.po --- a/i18n/es.po Mon Jun 07 12:39:15 2010 +0200 +++ b/i18n/es.po Mon Jun 07 13:22:24 2010 +0200 @@ -177,6 +177,10 @@ msgstr "1 0..1" #, python-format +msgid "<%s not specified>" +msgstr "" + +#, python-format msgid "" "
This schema of the data model excludes the meta-data, but you " "can also display a complete schema with meta-data.
" @@ -185,9 +189,6 @@ "pero se puede ver a un modelo completo con meta-datos." -msgid "" -msgstr "" - msgid "?*" msgstr "0..1 0..n" @@ -2667,6 +2668,9 @@ msgid "log in" msgstr "Identificarse" +msgid "log out first" +msgstr "" + msgid "login" msgstr "Clave de acesso" diff -r aa04ccb8dd62 -r 0f2ded880d01 i18n/fr.po --- a/i18n/fr.po Mon Jun 07 12:39:15 2010 +0200 +++ b/i18n/fr.po Mon Jun 07 13:22:24 2010 +0200 @@ -177,6 +177,10 @@ msgstr "1 0..1" #, python-format +msgid "<%s not specified>" +msgstr "<%s non spécifié>" + +#, python-format msgid "" "
This schema of the data model excludes the meta-data, but you " "can also display a complete schema with meta-data.
" @@ -184,9 +188,6 @@ "
Ce schéma du modèle de données exclue les méta-données, mais " "vous pouvez afficher un schéma complet.
" -msgid "" -msgstr "" - msgid "?*" msgstr "0..1 0..n" @@ -2705,6 +2706,9 @@ msgid "log in" msgstr "s'identifier" +msgid "log out first" +msgstr "déconnecter vous d'abord" + msgid "login" msgstr "identifiant" @@ -4081,6 +4085,3 @@ msgid "you should probably delete that property" msgstr "vous devriez probablement supprimer cette propriété" - -#~ msgid "schema-image" -#~ msgstr "image" diff -r aa04ccb8dd62 -r 0f2ded880d01 rset.py --- a/rset.py Mon Jun 07 12:39:15 2010 +0200 +++ b/rset.py Mon Jun 07 13:22:24 2010 +0200 @@ -15,9 +15,8 @@ # # You should have received a copy of the GNU Lesser General Public License along # with CubicWeb. If not, see . -"""The `ResultSet` class which is returned as result of an rql query +"""The `ResultSet` class which is returned as result of an rql query""" -""" __docformat__ = "restructuredtext en" from logilab.common.decorators import cached, clear_cache, copy_cache @@ -600,7 +599,11 @@ if rel is not None: index = rel.children[0].root_selection_index() if index is not None and self.rows[row][index]: - return self.get_entity(row, index), rel.r_type + try: + entity = self.get_entity(row, index) + return entity, rel.r_type + except NotAnEntity, exc: + return None, None return None, None @cached diff -r aa04ccb8dd62 -r 0f2ded880d01 server/migractions.py --- a/server/migractions.py Mon Jun 07 12:39:15 2010 +0200 +++ b/server/migractions.py Mon Jun 07 13:22:24 2010 +0200 @@ -416,7 +416,8 @@ 'vars': expression.mainvars, 'x': teid}, ask_confirm=False) - def _synchronize_rschema(self, rtype, syncrdefs=True, syncperms=True, syncprops=True): + def _synchronize_rschema(self, rtype, syncrdefs=True, + syncperms=True, syncprops=True): """synchronize properties of the persistent relation schema against its current definition: @@ -448,7 +449,8 @@ syncprops=syncprops, syncperms=syncperms) - def _synchronize_eschema(self, etype, syncperms=True): + def _synchronize_eschema(self, etype, syncrdefs=True, + syncperms=True, syncprops=True): """synchronize properties of the persistent entity schema against its current definition: @@ -465,40 +467,43 @@ try: eschema = self.fs_schema.eschema(etype) except KeyError: - return - repospschema = repoeschema.specializes() - espschema = eschema.specializes() - if repospschema and not espschema: - self.rqlexec('DELETE X specializes Y WHERE X is CWEType, X name %(x)s', - {'x': str(repoeschema)}, ask_confirm=False) - elif not repospschema and espschema: - self.rqlexec('SET X specializes Y WHERE X is CWEType, X name %(x)s, ' - 'Y is CWEType, Y name %(y)s', - {'x': str(repoeschema), 'y': str(espschema)}, - ask_confirm=False) - self.rqlexecall(ss.updateeschema2rql(eschema, repoeschema.eid), - ask_confirm=self.verbosity >= 2) - for rschema, targettypes, role in eschema.relation_definitions(True): - if rschema in VIRTUAL_RTYPES: - continue - if role == 'subject': - if not rschema in repoeschema.subject_relations(): - continue - subjtypes, objtypes = [etype], targettypes - else: # role == 'object' - if not rschema in repoeschema.object_relations(): - continue - subjtypes, objtypes = targettypes, [etype] - self._synchronize_rschema(rschema, syncperms=syncperms, - syncrdefs=False) - reporschema = self.repo.schema.rschema(rschema) - for subj in subjtypes: - for obj in objtypes: - if (subj, obj) not in reporschema.rdefs: - continue - self._synchronize_rdef_schema(subj, rschema, obj) + return # XXX somewhat unexpected, no?... + if syncprops: + repospschema = repoeschema.specializes() + espschema = eschema.specializes() + if repospschema and not espschema: + self.rqlexec('DELETE X specializes Y WHERE X is CWEType, X name %(x)s', + {'x': str(repoeschema)}, ask_confirm=False) + elif not repospschema and espschema: + self.rqlexec('SET X specializes Y WHERE X is CWEType, X name %(x)s, ' + 'Y is CWEType, Y name %(y)s', + {'x': str(repoeschema), 'y': str(espschema)}, + ask_confirm=False) + self.rqlexecall(ss.updateeschema2rql(eschema, repoeschema.eid), + ask_confirm=self.verbosity >= 2) if syncperms: self._synchronize_permissions(eschema, repoeschema.eid) + if syncrdefs: + for rschema, targettypes, role in eschema.relation_definitions(True): + if rschema in VIRTUAL_RTYPES: + continue + if role == 'subject': + if not rschema in repoeschema.subject_relations(): + continue + subjtypes, objtypes = [etype], targettypes + else: # role == 'object' + if not rschema in repoeschema.object_relations(): + continue + subjtypes, objtypes = targettypes, [etype] + self._synchronize_rschema(rschema, syncrdefs=False, + syncprops=syncprops, syncperms=syncperms) + reporschema = self.repo.schema.rschema(rschema) + for subj in subjtypes: + for obj in objtypes: + if (subj, obj) not in reporschema.rdefs: + continue + self._synchronize_rdef_schema(subj, rschema, obj, + syncprops=syncprops, syncperms=syncperms) def _synchronize_rdef_schema(self, subjtype, rtype, objtype, syncperms=True, syncprops=True): @@ -991,32 +996,23 @@ if ertype is not None: if isinstance(ertype, (tuple, list)): assert len(ertype) == 3, 'not a relation definition' - assert syncprops, 'can\'t update permission for a relation definition' self._synchronize_rdef_schema(ertype[0], ertype[1], ertype[2], syncperms=syncperms, syncprops=syncprops) else: erschema = self.repo.schema[ertype] if isinstance(erschema, CubicWebRelationSchema): - self._synchronize_rschema(erschema, syncperms=syncperms, - syncprops=syncprops, - syncrdefs=syncrdefs) - elif syncprops: - self._synchronize_eschema(erschema, syncperms=syncperms) + self._synchronize_rschema(erschema, syncrdefs=syncrdefs, + syncperms=syncperms, + syncprops=syncprops) else: - self._synchronize_permissions(self.fs_schema[ertype], erschema.eid) + self._synchronize_eschema(erschema, syncrdefs=syncrdefs, + syncperms=syncperms, + syncprops=syncprops) else: for etype in self.repo.schema.entities(): - if syncprops: - self._synchronize_eschema(etype, syncperms=syncperms) - else: - try: - fseschema = self.fs_schema[etype] - except KeyError: - # entity type in the repository schema but not anymore - # on the fs schema - continue - self._synchronize_permissions(fseschema, etype.eid) + self._synchronize_eschema(etype, syncrdefs=syncrdefs, + syncprops=syncprops, syncperms=syncperms) if commit: self.commit() diff -r aa04ccb8dd62 -r 0f2ded880d01 server/querier.py --- a/server/querier.py Mon Jun 07 12:39:15 2010 +0200 +++ b/server/querier.py Mon Jun 07 13:22:24 2010 +0200 @@ -419,7 +419,7 @@ # list of new or updated entities definition (utils.Entity) self.e_defs = [[]] # list of new relation definition (3-uple (from_eid, r_type, to_eid) - self.r_defs = [] + self.r_defs = set() # indexes to track entity definitions bound to relation definitions self._r_subj_index = {} self._r_obj_index = {} @@ -432,7 +432,7 @@ def add_relation_def(self, rdef): """add an relation definition to build""" - self.r_defs.append(rdef) + self.r_defs.add(rdef) if not isinstance(rdef[0], int): self._r_subj_index.setdefault(rdef[0], []).append(rdef) if not isinstance(rdef[2], int): @@ -458,9 +458,9 @@ for i, row in enumerate(self.e_defs[:]): self.e_defs[i][colidx] = edefs[0] samplerow = self.e_defs[i] - for edef in edefs[1:]: + for edef_ in edefs[1:]: row = samplerow[:] - row[colidx] = edef + row[colidx] = edef_ self.e_defs.append(row) # now, see if this entity def is referenced as subject in some relation # definition @@ -469,8 +469,8 @@ expanded = self._expanded(rdef) result = [] for exp_rdef in expanded: - for edef in edefs: - result.append( (edef, exp_rdef[1], exp_rdef[2]) ) + for edef_ in edefs: + result.append( (edef_, exp_rdef[1], exp_rdef[2]) ) self._expanded_r_defs[rdef] = result # and finally, see if this entity def is referenced as object in some # relation definition @@ -479,8 +479,8 @@ expanded = self._expanded(rdef) result = [] for exp_rdef in expanded: - for edef in edefs: - result.append( (exp_rdef[0], exp_rdef[1], edef) ) + for edef_ in edefs: + result.append( (exp_rdef[0], exp_rdef[1], edef_) ) self._expanded_r_defs[rdef] = result def _expanded(self, rdef): diff -r aa04ccb8dd62 -r 0f2ded880d01 server/sources/rql2sql.py --- a/server/sources/rql2sql.py Mon Jun 07 12:39:15 2010 +0200 +++ b/server/sources/rql2sql.py Mon Jun 07 13:22:24 2010 +0200 @@ -556,8 +556,8 @@ if not isinstance(vref, Constant)) if having: # filter out constants as for GROUP BY - having = ','.join(vref.accept(self) for vref in having - if not isinstance(vref, Constant)) + having = ' AND '.join(term.accept(self) for term in having + if not isinstance(term, Constant)) if needwrap: sql = '%s FROM (%s) AS T1' % (self._selection_sql(outerselection, distinct, needalias), diff -r aa04ccb8dd62 -r 0f2ded880d01 server/test/unittest_querier.py --- a/server/test/unittest_querier.py Mon Jun 07 12:39:15 2010 +0200 +++ b/server/test/unittest_querier.py Mon Jun 07 13:22:24 2010 +0200 @@ -915,12 +915,33 @@ self.assert_(rset.rows) self.assertEquals(rset.description, [('Personne', 'Societe',)]) + def test_insert_7_2(self): + self.execute("INSERT Personne X, Societe Y: X nom N, Y nom 'toto', X travaille Y WHERE U login N") + rset = self.execute('Any X, Y WHERE Y nom "toto", X travaille Y') + self.assertEquals(len(rset), 2) + self.assertEquals(rset.description, [('Personne', 'Societe',), + ('Personne', 'Societe',)]) + def test_insert_8(self): self.execute("INSERT Societe Y, Personne X: Y nom N, X nom 'toto', X travaille Y WHERE U login 'admin', U login N") rset = self.execute('Any X, Y WHERE X nom "toto", Y nom "admin", X travaille Y') self.assert_(rset.rows) self.assertEquals(rset.description, [('Personne', 'Societe',)]) + def test_insert_9(self): + self.execute("INSERT Societe X: X nom 'Lo'") + self.execute("INSERT Societe X: X nom 'Gi'") + self.execute("INSERT SubDivision X: X nom 'Lab'") + rset = self.execute("INSERT Personne X: X nom N, X travaille Y, X travaille_subdivision Z WHERE Y is Societe, Z is SubDivision, Y nom N") + self.assertEquals(len(rset), 2) + self.assertEquals(rset.description, [('Personne',), ('Personne',)]) + # self.assertSetEquals(set(x.nom for x in rset.entities()), + # ['Lo', 'Gi']) + # self.assertSetEquals(set(y.nom for x in rset.entities() for y in x.travaille), + # ['Lo', 'Gi']) + # self.assertEquals([y.nom for x in rset.entities() for y in x.travaille_subdivision], + # ['Lab', 'Lab']) + def test_insert_query_error(self): self.assertRaises(Exception, self.execute, diff -r aa04ccb8dd62 -r 0f2ded880d01 test/unittest_rset.py --- a/test/unittest_rset.py Mon Jun 07 12:39:15 2010 +0200 +++ b/test/unittest_rset.py Mon Jun 07 13:22:24 2010 +0200 @@ -397,5 +397,9 @@ '(Any X,N WHERE X is CWGroup, X name N)' ')') + def test_count_users_by_date(self): + rset = self.execute('Any D, COUNT(U) GROUPBY D WHERE U is CWUser, U creation_date D') + self.assertEquals(rset.related_entity(0,0), (None, None)) + if __name__ == '__main__': unittest_main() diff -r aa04ccb8dd62 -r 0f2ded880d01 view.py --- a/view.py Mon Jun 07 12:39:15 2010 +0200 +++ b/view.py Mon Jun 07 13:22:24 2010 +0200 @@ -51,7 +51,6 @@ cubicweb:accesskey CDATA #IMPLIED cubicweb:actualrql CDATA #IMPLIED cubicweb:dataurl CDATA #IMPLIED - cubicweb:displayactions CDATA #IMPLIED cubicweb:facetName CDATA #IMPLIED cubicweb:facetargs CDATA #IMPLIED cubicweb:fallbackvid CDATA #IMPLIED diff -r aa04ccb8dd62 -r 0f2ded880d01 web/data/cubicweb.edition.js --- a/web/data/cubicweb.edition.js Mon Jun 07 12:39:15 2010 +0200 +++ b/web/data/cubicweb.edition.js Mon Jun 07 13:22:24 2010 +0200 @@ -471,13 +471,15 @@ // Failures _clearPreviousErrors(formid); var descr = result[1]; + var errmsg; // Unknown structure - if (!isArrayLike(descr) || descr.length != 2) { - updateMessage(descr); - return false; + if ( !isArrayLike(descr) || descr.length != 2 ) { + errmsg = descr; + } else { + _displayValidationerrors(formid, descr[0], descr[1]); + errmsg = _('please correct errors below'); } - _displayValidationerrors(formid, descr[0], descr[1]); - updateMessage(_('please correct errors below')); + updateMessage(errmsg); // ensure the browser does not scroll down document.location.hash = '#header'; return false; diff -r aa04ccb8dd62 -r 0f2ded880d01 web/data/cubicweb.facets.js --- a/web/data/cubicweb.facets.js Mon Jun 07 12:39:15 2010 +0200 +++ b/web/data/cubicweb.facets.js Mon Jun 07 13:22:24 2010 +0200 @@ -56,13 +56,7 @@ } var toupdate = result[1]; var extraparams = vidargs; - var displayactions = jQuery('#' + divid).attr('cubicweb:displayactions'); - if (displayactions) { - extraparams['displayactions'] = displayactions; - } - if (paginate) { - extraparams['paginate'] = '1'; - } + if (paginate) { extraparams['paginate'] = '1'; } // XXX in vidargs // copy some parameters // XXX cleanup vid/divid mess // if vid argument is specified , the one specified in form params will diff -r aa04ccb8dd62 -r 0f2ded880d01 web/formfields.py --- a/web/formfields.py Mon Jun 07 12:39:15 2010 +0200 +++ b/web/formfields.py Mon Jun 07 13:22:24 2010 +0200 @@ -439,9 +439,11 @@ # attribute or relation return True # if it's a non final relation, we need the eids - if isinstance(previous_value, tuple): + # XXX underlying regression: getattr(ent, 'foo') used to return + # a tuple, now we get a list + if isinstance(previous_value, (list, tuple)): # widget should return a set of untyped eids - previous_value = set(unicode(e.eid) for e in previous_value) + previous_value = set(e.eid for e in previous_value) try: new_value = self.process_form_value(form) except ProcessFormError: diff -r aa04ccb8dd62 -r 0f2ded880d01 web/views/autoform.py --- a/web/views/autoform.py Mon Jun 07 12:39:15 2010 +0200 +++ b/web/views/autoform.py Mon Jun 07 13:22:24 2010 +0200 @@ -650,13 +650,13 @@ # pre 3.8.3 compat def set_action(self, action): self._action = action - @deprecated('[3.9] use form.form_action()') def get_action(self): try: return self._action except AttributeError: return self._cw.build_url(self._default_form_action_path) - action = property(get_action, set_action) + action = property(deprecated('[3.9] use form.form_action()')(get_action), + set_action) @iclassmethod def field_by_name(cls_or_self, name, role=None, eschema=None): diff -r aa04ccb8dd62 -r 0f2ded880d01 web/views/editforms.py --- a/web/views/editforms.py Mon Jun 07 12:39:15 2010 +0200 +++ b/web/views/editforms.py Mon Jun 07 13:22:24 2010 +0200 @@ -340,16 +340,13 @@ self._build_renderer(entity, rtype, role)) def should_edit_attribute(self, entity, rschema, form): - rtype = str(rschema) - rdef = entity.e_schema.rdef(rtype) - afs = uicfg.autoform_section.etype_get( - entity.__regid__, rtype, 'subject', rdef.object) - if 'main_hidden' in afs or not entity.cw_has_perm('update'): + if not entity.has_perm('update'): return False + rdef = entity.e_schema.rdef(rschema) if not rdef.has_perm(self._cw, 'update', eid=entity.eid): return False try: - form.field_by_name(rtype, 'subject', entity.e_schema) + form.field_by_name(str(rschema), 'subject', entity.e_schema) except FieldNotFound: return False return True @@ -439,15 +436,27 @@ _onclick = (u"loadInlineEditionFormOptions(%(eid)s, '%(rtype)s', " "'%(divid)s', %(options)s);") + def should_edit_attribute(self, entity, rschema, form): + rdef = entity.e_schema.rdef(rschema) + afs = uicfg.autoform_section.etype_get( + entity.__regid__, rschema, 'subject', rdef.object) + if 'main_hidden' in afs: + return False + return super(AutoClickAndEditFormView, self).should_edit_attribute( + entity, rschema, form) + def should_edit_relation(self, entity, rschema, role, rvid): eschema = entity.e_schema - rtype = str(rschema) - # XXX check autoform_section. what if 'generic'? - dispctrl = _pvdc.etype_get(eschema, rtype, role) + dispctrl = _pvdc.etype_get(eschema, rschema, role) vid = dispctrl.get('vid', 'reledit') if vid != 'reledit': # reledit explicitly disabled return False - if eschema.rdef(rschema, role).composite == role: + rdef = eschema.rdef(rschema, role) + if rdef.composite == role: + return False + afs = uicfg.autoform_section.etype_get( + entity.__regid__, rschema, role, rdef.object) + if 'main_hidden' in afs: return False return super(AutoClickAndEditFormView, self).should_edit_relation( entity, rschema, role, rvid) diff -r aa04ccb8dd62 -r 0f2ded880d01 web/views/forms.py --- a/web/views/forms.py Mon Jun 07 12:39:15 2010 +0200 +++ b/web/views/forms.py Mon Jun 07 13:22:24 2010 +0200 @@ -196,9 +196,13 @@ _default_form_action_path = 'edit' def form_action(self): - if self.action is None: + try: + action = self.get_action() # avoid spurious warning w/ autoform bw compat property + except AttributeError: + action = self.action + if action is None: return self._cw.build_url(self._default_form_action_path) - return self.action + return action @deprecated('[3.6] use .add_hidden(name, value, **kwargs)') def form_add_hidden(self, name, value=None, **kwargs): diff -r aa04ccb8dd62 -r 0f2ded880d01 web/views/tableview.py --- a/web/views/tableview.py Mon Jun 07 12:39:15 2010 +0200 +++ b/web/views/tableview.py Mon Jun 07 13:22:24 2010 +0200 @@ -46,7 +46,7 @@ finalview = 'final' def form_filter(self, divid, displaycols, displayactions, displayfilter, - hidden=True): + paginate, hidden=True): rqlst = self.cw_rset.syntax_tree() # union not yet supported if len(rqlst.children) != 1: @@ -60,7 +60,8 @@ wdgs = [wdg for wdg in wdgs if wdg is not None] if wdgs: self._generate_form(divid, baserql, wdgs, hidden, - vidargs={'displaycols': displaycols, + vidargs={'paginate': paginate, + 'displaycols': displaycols, 'displayactions': displayactions, 'displayfilter': displayfilter}) return self.show_hide_actions(divid, not hidden) @@ -162,19 +163,16 @@ self.w(u'

%s

\n' % title) if displayfilter: actions += self.form_filter(divid, displaycols, displayfilter, - displayactions) + displayactions, paginate) elif displayfilter: actions += self.show_hide_actions(divid, True) - self.w(u'
' % divid) if displayactions: actionsbycat = self._cw.vreg['actions'].possible_actions(req, self.cw_rset) for action in actionsbycat.get('mainactions', ()): for action in action.actual_actions(): actions.append( (action.url(), req._(action.title), action.html_class(), None) ) - self.w(u' cubicweb:displayactions="1">') # close
') # close