merge stable
authorKatia Saurfelt <katia.saurfelt@logilab.fr>
Tue, 19 May 2009 12:07:03 +0200
branchstable
changeset 1866 118c7528d08f
parent 1865 62d3726ad8cb (current diff)
parent 1861 21fae1546ac4 (diff)
child 1867 b2fe73a55899
merge
--- a/dbapi.py	Tue May 19 11:50:15 2009 +0200
+++ b/dbapi.py	Tue May 19 12:07:03 2009 +0200
@@ -325,6 +325,11 @@
         self.vreg = None
         # session's data
         self.data = {}
+        # XXX < 3.2 bw compat
+        if 'EUser' in self._repo.get_schema():
+            self._user_etype = 'EUser'
+        else:
+            self._user_etype = 'CWUser'
 
     def __repr__(self):
         if self.anonymous_connection:
@@ -430,8 +435,8 @@
         eid, login, groups, properties = self._repo.user_info(self.sessionid, props)
         if req is None:
             req = self.request()
-        rset = req.eid_rset(eid, 'CWUser')
-        user = self.vreg.etype_class('CWUser')(req, rset, row=0, groups=groups,
+        rset = req.eid_rset(eid, self._user_etype)
+        user = self.vreg.etype_class(self._user_etype)(req, rset, row=0, groups=groups,
                                                properties=properties)
         user['login'] = login # cache login
         return user
--- a/devtools/devctl.py	Tue May 19 11:50:15 2009 +0200
+++ b/devtools/devctl.py	Tue May 19 12:07:03 2009 +0200
@@ -77,11 +77,11 @@
             if mod.__file__.startswith(path):
                 del sys.modules[name]
                 break
-        # fresh rtags
-        from cubicweb import rtags
-        from cubicweb.web import uicfg
-        rtags.RTAGS[:] = []
-        reload(uicfg)
+    # fresh rtags
+    from cubicweb import rtags
+    from cubicweb.web import uicfg
+    rtags.RTAGS[:] = []
+    reload(uicfg)
 
 def generate_schema_pot(w, cubedir=None):
     """generate a pot file with schema specific i18n messages
--- a/devtools/fake.py	Tue May 19 11:50:15 2009 +0200
+++ b/devtools/fake.py	Tue May 19 12:07:03 2009 +0200
@@ -79,6 +79,11 @@
         self._session_data = {}
         self._headers = {}
 
+    def get_session_data(self, key, default=None, pop=False):
+        if pop:
+            return self._session_data.pop(key, default)
+        return self._session_data.get(key, default)
+
     def header_accept_language(self):
         """returns an ordered list of preferred languages"""
         return ('en',)
--- a/entities/__init__.py	Tue May 19 11:50:15 2009 +0200
+++ b/entities/__init__.py	Tue May 19 12:07:03 2009 +0200
@@ -57,16 +57,6 @@
             return '%s DESC' % var
         return None
 
-    @classmethod
-    def __initialize__(cls):
-        super(ANYENTITY, cls).__initialize__() # XXX
-        # set a default_ATTR method for rich text format fields
-        # XXX move this away once the old widgets have been dropped!
-        eschema = cls.e_schema
-        for metaattr, (metadata, attr) in eschema.meta_attributes().iteritems():
-            if metadata == 'format' and not hasattr(cls, 'default_%s' % metaattr):
-                setattr(cls, 'default_%s' % metaattr, cls._default_format)
-
     # meta data api ###########################################################
 
     def dc_title(self):
@@ -269,9 +259,6 @@
         from cubicweb.web.views.autoform import AutomaticEntityForm
         return AutomaticEntityForm.esrelations_by_category(self, categories, permission)
 
-    def _default_format(self):
-        return self.req.property_value('ui.default-text-format')
-
     def attribute_values(self, attrname):
         if self.has_eid() or attrname in self:
             try:
--- a/rtags.py	Tue May 19 11:50:15 2009 +0200
+++ b/rtags.py	Tue May 19 12:07:03 2009 +0200
@@ -24,7 +24,8 @@
     This class associates a single tag to each key.
     """
     _allowed_values = None
-    def __init__(self, initfunc=None, allowed_values=None):
+    def __init__(self, name=None, initfunc=None, allowed_values=None):
+        self._name = name or '<unknown>'
         self._tagdefs = {}
         if allowed_values is not None:
             self._allowed_values = allowed_values
@@ -32,7 +33,7 @@
         register_rtag(self)
 
     def __repr__(self):
-        return repr(self._tagdefs)
+        return '%s: %s' % (self._name, repr(self._tagdefs))
 
     # dict compat
     def __getitem__(self, key):
@@ -95,7 +96,9 @@
         #else:
         stype, rtype, otype, tagged = [str(k) for k in key]
         if self._allowed_values is not None:
-            assert tag in self._allowed_values, '%r is not an allowed tag' % tag
+            assert tag in self._allowed_values, \
+                   '%r is not an allowed tag (should be in %s)' % (
+                tag, self._allowed_values)
         self._tagdefs[(rtype, tagged, stype, otype)] = tag
 
     # rtag runtime api ########################################################
--- a/web/form.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/form.py	Tue May 19 12:07:03 2009 +0200
@@ -372,10 +372,15 @@
             return self.form_previous_values[qname]
         if qname in self.req.form:
             return self.req.form[qname]
+        if field.name in self.req.form:
+            return self.req.form[field.name]
         return None
 
     def form_field_value(self, field, load_bytes=False):
         """return field's *typed* value"""
+        myattr = '%s_%s_default' % (field.role, field.name)
+        if hasattr(self, myattr):
+            return getattr(self, myattr)()
         value = field.initial
         if callable(value):
             value = value(self)
--- a/web/formfields.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/formfields.py	Tue May 19 12:07:03 2009 +0200
@@ -213,20 +213,21 @@
         try:
             return req.data[self]
         except KeyError:
+            fkwargs = {}
             if self.use_fckeditor(form):
                 # if fckeditor is used and format field isn't explicitly
                 # deactivated, we want an hidden field for the format
-                widget = HiddenInput()
-                choices = None
+                fkwargs['widget'] = HiddenInput()
+                fkwargs['initial'] = 'text/html'
             else:
                 # else we want a format selector
-                # XXX compute vocabulary
-                widget = Select()
+                fkwargs['widget'] = Select()
+                fkwargs['widget'].attrs['size'] = 1
                 fcstr = FormatConstraint()
-                choices = [(req._(fmt), fmt) for fmt in fcstr.vocabulary(req=req)]
-                widget.attrs['size'] = 1
-            field = StringField(name=self.name + '_format', widget=widget,
-                                choices=choices)
+                fkwargs['choices'] = fcstr.vocabulary(req=req)
+                fkwargs['internationalizable'] = True
+                fkwargs['initial'] = lambda f: f.form_field_format(self)
+            field = StringField(name=self.name + '_format', **fkwargs)
             req.data[self] = field
             return field
 
--- a/web/test/unittest_form.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/test/unittest_form.py	Tue May 19 12:07:03 2009 +0200
@@ -64,7 +64,14 @@
         self.assertEquals(len(states), 1)
         self.assertEquals(states[0][0], u'deactivated') # list of (combobox view, state eid)
 
-
+    def test_consider_req_form_params(self):
+        e = self.etype_instance('CWUser')
+        e.eid = 'A'
+        form = EntityFieldsForm(self.request(login=u'toto'), None, entity=e)
+        field = StringField(name='login', eidparam=True)
+        form.append_field(field)
+        form.form_build_context({})
+        self.assertEquals(form.form_field_display_value(field, {}), 'toto')
 
     # form view tests #########################################################
 
--- a/web/test/unittest_formfields.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/test/unittest_formfields.py	Tue May 19 12:07:03 2009 +0200
@@ -1,12 +1,15 @@
 """unittests for cw.web.formfields"""
 
+from logilab.common.testlib import TestCase, unittest_main
+
 from yams.constraints import StaticVocabularyConstraint, SizeConstraint
-from logilab.common.testlib import TestCase, unittest_main
+
 from cubicweb.devtools import TestServerConfiguration
+from cubicweb.devtools.testlib import EnvBasedTC
+from cubicweb.web.form import EntityFieldsForm
 from cubicweb.web.formwidgets import PasswordInput, TextArea, Select
 from cubicweb.web.formfields import *
-from cubicweb.entities.wfobjs import State
-from cubicweb.entities.authobjs import CWUser
+
 from cubes.file.entities import File
 
 config = TestServerConfiguration('data')
@@ -43,12 +46,13 @@
         self.assertEquals(description_format_field.sort, True)
         self.assertEquals(description_format_field.initial(None), 'text/rest')
 
+
 #         wikiid_field = guess_field(state_schema, schema['wikiid'])
 #         self.assertIsInstance(wikiid_field, StringField)
 #         self.assertEquals(wikiid_field.required, False)
 
 
-    def test_euser_fields(self):
+    def test_cwuser_fields(self):
         upassword_field = guess_field(cwuser_schema, schema['upassword'])
         self.assertIsInstance(upassword_field, StringField)
         self.assertIsInstance(upassword_field.widget, PasswordInput)
@@ -89,5 +93,21 @@
                           [SizeConstraint, StaticVocabularyConstraint])
         self.assertIsInstance(salesterm_field.widget, Select)
 
+class MoreFieldsTC(EnvBasedTC):
+    def test_rtf_format_field(self):
+        req = self.request()
+        req.use_fckeditor = lambda: False
+        e = self.etype_instance('State')
+        form = EntityFieldsForm(req, entity=e)
+        description_field = guess_field(state_schema, schema['description'])
+        description_format_field = description_field.get_format_field(form)
+        self.assertEquals(description_format_field.internationalizable, True)
+        self.assertEquals(description_format_field.sort, True)
+        # unlike below, initial is bound to form.form_field_format
+        self.assertEquals(description_format_field.initial(form), 'text/html')
+        self.execute('INSERT CWProperty X: X pkey "ui.default-text-format", X value "text/rest", X for_user U WHERE U login "admin"')
+        self.commit()
+        self.assertEquals(description_format_field.initial(form), 'text/rest')
+
 if __name__ == '__main__':
     unittest_main()
--- a/web/uicfg.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/uicfg.py	Tue May 19 12:07:03 2009 +0200
@@ -97,8 +97,9 @@
             section = 'sideboxes'
         rtag.tag_relation((sschema, rschema, oschema, role), section)
 
-primaryview_section = RelationTags(init_primaryview_section,
-                                    frozenset(('attributes', 'relations',
+primaryview_section = RelationTags('primaryview_section',
+                                   init_primaryview_section,
+                                   frozenset(('attributes', 'relations',
                                                'sideboxes', 'hidden')))
 for rtype in ('eid', 'creation_date', 'modification_date',
               'is', 'is_instance_of', 'identity',
@@ -140,7 +141,8 @@
         rtag.tag_relation((sschema, rschema, oschema, role), displayinfo)
     displayinfo.setdefault('label', label)
 
-primaryview_display_ctrl = DisplayCtrlRelationTags(init_primaryview_display_ctrl)
+primaryview_display_ctrl = DisplayCtrlRelationTags('primaryview_display_ctrl',
+                                                   init_primaryview_display_ctrl)
 
 
 # index view configuration ####################################################
@@ -178,7 +180,7 @@
             section = 'generic'
         rtag.tag_relation((sschema, rschema, oschema, role), section)
 
-autoform_section = RelationTags(init_autoform_section,
+autoform_section = RelationTags('autoform_section', init_autoform_section,
                                 set(('primary', 'secondary', 'generic',
                                      'metadata', 'generated')))
 # use primary and not generated for eid since it has to be an hidden
@@ -217,7 +219,7 @@
 
 
 # relations'field class
-autoform_field = RelationTags()
+autoform_field = RelationTags('autoform_field')
 
 # relations'field explicit kwargs (given to field's __init__)
 autoform_field_kwargs = RelationTags()
@@ -231,7 +233,7 @@
 # inlined view flag for non final relations: when True for an entry, the
 # entity(ies) at the other end of the relation will be editable from the
 # form of the edited entity
-autoform_is_inlined = RelationTagsBool()
+autoform_is_inlined = RelationTagsBool('autoform_is_inlined')
 autoform_is_inlined.tag_subject_of(('*', 'use_email', '*'), True)
 autoform_is_inlined.tag_subject_of(('CWRelation', 'relation_type', '*'), True)
 autoform_is_inlined.tag_subject_of(('CWRelation', 'from_entity', '*'), True)
@@ -241,7 +243,7 @@
 # set of tags of the form <action>_on_new on relations. <action> is a
 # schema action (add/update/delete/read), and when such a tag is found
 # permissions checking is by-passed and supposed to be ok
-autoform_permissions_overrides = RelationTagsSet()
+autoform_permissions_overrides = RelationTagsSet('autoform_permissions_overrides')
 
 
 # boxes.EditBox configuration #################################################
@@ -254,7 +256,8 @@
                rschema.rproperty(sschema, oschema, 'composite') == role:
             rtag.tag_relation((sschema, rschema, oschema, role), True)
 
-actionbox_appearsin_addmenu = RelationTagsBool(init_actionbox_appearsin_addmenu)
+actionbox_appearsin_addmenu = RelationTagsBool('actionbox_appearsin_addmenu',
+                                               init_actionbox_appearsin_addmenu)
 actionbox_appearsin_addmenu.tag_subject_of(('*', 'is', '*'), False)
 actionbox_appearsin_addmenu.tag_object_of(('*', 'is', '*'), False)
 actionbox_appearsin_addmenu.tag_subject_of(('*', 'is_instance_of', '*'), False)
--- a/web/views/basecontrollers.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/views/basecontrollers.py	Tue May 19 12:07:03 2009 +0200
@@ -382,11 +382,7 @@
             ctrl.publish(None, fromjson=True)
         except ValidationError, err:
             self.req.cnx.rollback()
-            if not err.entity or isinstance(err.entity, (long, int)):
-                eid = err.entity
-            else:
-                eid = err.entity.eid
-            return (False, (eid, err.errors))
+            return (False, (err.entity, err.errors))
         except Redirect, redir:
             return (True, redir.location)
         except Exception, err:
@@ -487,6 +483,24 @@
         rql = 'DELETE B bookmarked_by U WHERE B eid %(b)s, U eid %(u)s'
         self.req.execute(rql, {'b': typed_eid(beid), 'u' : self.req.user.eid})
 
+    def js_node_clicked(self, treeid, nodeeid):
+        """add/remove eid in treestate cookie"""
+        from cubicweb.web.views.treeview import treecookiename
+        cookies = self.req.get_cookie()
+        statename = treecookiename(treeid)
+        treestate = cookies.get(statename)
+        if treestate is None:
+            cookies[statename] = nodeeid
+            self.req.set_cookie(cookies, statename)
+        else:
+            marked = set(filter(None, treestate.value.split(';')))
+            if nodeeid in marked:
+                marked.remove(nodeeid)
+            else:
+                marked.add(nodeeid)
+            cookies[statename] = ';'.join(marked)
+            self.req.set_cookie(cookies, statename)
+
     def js_set_cookie(self, cookiename, cookievalue):
         # XXX we should consider jQuery.Cookie
         cookiename, cookievalue = str(cookiename), str(cookievalue)
--- a/web/views/basetemplates.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/views/basetemplates.py	Tue May 19 12:07:03 2009 +0200
@@ -7,7 +7,6 @@
 """
 __docformat__ = "restructuredtext en"
 
-
 from logilab.mtconverter import html_escape
 
 from cubicweb.vregistry import objectify_selector
--- a/web/views/boxes.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/views/boxes.py	Tue May 19 12:07:03 2009 +0200
@@ -99,10 +99,10 @@
         eschema = entity.e_schema
         for rschema, teschema, x in self.add_related_schemas(entity):
             if x == 'subject':
-                label = '%s %s %s %s' % (eschema, rschema, teschema, x)
+                label = 'add %s %s %s %s' % (eschema, rschema, teschema, x)
                 url = self.linkto_url(entity, rschema, teschema, 'object')
             else:
-                label = '%s %s %s %s' % (teschema, rschema, eschema, x)
+                label = 'add %s %s %s %s' % (teschema, rschema, eschema, x)
                 url = self.linkto_url(entity, rschema, teschema, 'subject')
             actions.append(self.mk_action(_(label), url))
         return actions
--- a/web/views/editforms.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/views/editforms.py	Tue May 19 12:07:03 2009 +0200
@@ -52,7 +52,7 @@
     # else we will only delete the displayed page
     need_navigation = False
 
-    def call(self):
+    def call(self, onsubmit=None):
         """ask for confirmation before real deletion"""
         req, w = self.req, self.w
         _ = req._
@@ -61,7 +61,7 @@
         # XXX above message should have style of a warning
         w(u'<h4>%s</h4>\n' % _('Do you want to delete the following element(s) ?'))
         form = CompositeForm(req, domid='deleteconf', copy_nav_params=True,
-                             action=self.build_url('edit'), onsubmit=None,
+                             action=self.build_url('edit'), onsubmit=onsubmit,
                              form_buttons=[Button(stdmsgs.YES, cwaction='delete'),
                                            Button(stdmsgs.NO, cwaction='cancel')])
         done = set()
@@ -350,7 +350,8 @@
     def render_form(self, entity, peid, rtype, role, **kwargs):
         """fetch and render the form"""
         form = self.vreg.select_object('forms', 'edition', self.req, None,
-                                       entity=entity, set_error_url=False)
+                                       entity=entity, set_error_url=False,
+                                       copy_nav_params=False)
         self.add_hiddens(form, entity, peid, rtype, role)
         divid = '%s-%s-%s' % (peid, rtype, entity.eid)
         title = self.schema.rschema(rtype).display_name(self.req, role)
--- a/web/views/treeview.py	Tue May 19 11:50:15 2009 +0200
+++ b/web/views/treeview.py	Tue May 19 12:07:03 2009 +0200
@@ -13,7 +13,6 @@
 from cubicweb.interfaces import ITree
 from cubicweb.selectors import implements
 from cubicweb.view import EntityView
-from cubicweb.web.views.basecontrollers import jsonize, JSonController
 
 def treecookiename(treeid):
     return str('treestate-%s' % treeid)
@@ -149,21 +148,3 @@
             self.wview(parentvid, self.req.execute(rql), treeid=treeid, initial_load=False)
         w(u'</li>')
 
-@monkeypatch(JSonController)
-@jsonize
-def js_node_clicked(self, treeid, nodeeid):
-    """add/remove eid in treestate cookie"""
-    cookies = self.req.get_cookie()
-    statename = treecookiename(treeid)
-    treestate = cookies.get(statename)
-    if treestate is None:
-        cookies[statename] = nodeeid
-        self.req.set_cookie(cookies, statename)
-    else:
-        marked = set(filter(None, treestate.value.split(';')))
-        if nodeeid in marked:
-            marked.remove(nodeeid)
-        else:
-            marked.add(nodeeid)
-        cookies[statename] = ';'.join(marked)
-        self.req.set_cookie(cookies, statename)