# -*- coding: utf-8 -*-
-import ir_fields
import view
import website
import ir_qweb
+
+import test_models
+++ /dev/null
-# -*- coding: utf-8 -*-
-from lxml import etree, html
-
-from openerp.osv import orm, fields
-from openerp.tools import ustr
-
-class converter(orm.Model):
- _inherit = 'ir.fields.converter'
-
- def _html_to_integer(self, cr, uid, model, column, value, context=None):
- return int(value.text_content().strip()), []
-
- def _html_to_float(self, cr, uid, model, column, value, context=None):
- return float(value.text_content().strip()), []
-
- def _html_to_passthrough(self, cr, uid, model, column, value, context=None):
- return value.text_content().strip(), []
-
- _html_to_char = _html_to_date = _html_to_datetime = _html_to_passthrough
-
- def _html_to_text(self, cr, uid, model, column, value, context=None):
- return value.text_content(), []
-
- def _html_to_selection(self, cr, uid, model, column, value, context=None):
- text = value.text_content().strip()
-
- selection = column.reify(cr, uid, model, column, context=context)
- for k, v in selection:
- if isinstance(v, str):
- v = ustr(v)
- if text == v:
- return k, []
-
- warning = u"No value found for label %s in selection %s" % (text, selection)
- # FIXME: ?
- return False, [Warning(warning.encode('utf-8'))]
-
- def _html_to_many2one(self, cr, uid, model, column, value, context=None):
- matches = self.pool[column._obj].name_search(
- cr, uid, name=value.text_content().strip(), context=context)
- # FIXME: more than one match, error reporting
- return matches[0][0], []
-
- def _html_to_html(self, cr, uid, model, column, value, context=None):
- content = []
- if value.text: content.append(value.text)
- content.extend(html.tostring(child)
- for child in value.iterchildren(tag=etree.Element))
- return '\n'.join(content), []
-
-
-class test_converter(orm.Model):
- _name = 'website.converter.test'
-
- _columns = {
- 'char': fields.char(),
- 'integer': fields.integer(),
- 'float': fields.float(),
- 'numeric': fields.float(digits=(16, 2)),
- 'many2one': fields.many2one('website.converter.test.sub'),
- 'binary': fields.binary(),
- 'date': fields.date(),
- 'datetime': fields.datetime(),
- 'selection': fields.selection([
- (1, "réponse A"),
- (2, "réponse B"),
- (3, "réponse C"),
- (4, "réponse D"),
- ]),
- 'selection_str': fields.selection([
- ('A', "Qu'il n'est pas arrivé à Toronto"),
- ('B', "Qu'il était supposé arriver à Toronto"),
- ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
- ('D', "La réponse D"),
- ], string="Lorsqu'un pancake prend l'avion à destination de Toronto et "
- "qu'il fait une escale technique à St Claude, on dit:"),
- 'html': fields.html(),
- 'text': fields.text(),
- }
-
-
-class test_converter_sub(orm.Model):
- _name = 'website.converter.test.sub'
-
- _columns = {
- 'name': fields.char(),
- }
import itertools
import werkzeug.utils
+from lxml import etree, html
from openerp.osv import orm, fields
+from openerp.tools import ustr
class QWeb(orm.AbstractModel):
""" QWeb object for rendering stuff in the website context
[('data-oe-translate', 1 if column.translate else 0)]
)
+ def value_from_string(self, value):
+ return value
+
+ def from_html(self, cr, uid, model, column, element, context=None):
+ return self.value_from_string(element.text_content().strip())
+
+class Integer(orm.AbstractModel):
+ _name = 'website.qweb.field.integer'
+ _inherit = ['website.qweb.field']
+
+ value_from_string = int
+
class Float(orm.AbstractModel):
_name = 'website.qweb.field.float'
_inherit = ['website.qweb.field', 'ir.qweb.field.float']
+ value_from_string = float
+
class Text(orm.AbstractModel):
_name = 'website.qweb.field.text'
_inherit = ['website.qweb.field', 'ir.qweb.field.text']
+ def from_html(self, cr, uid, model, column, element, context=None):
+ return element.text_content()
+
class Selection(orm.AbstractModel):
_name = 'website.qweb.field.selection'
_inherit = ['website.qweb.field', 'ir.qweb.field.selection']
+ def from_html(self, cr, uid, model, column, element, context=None):
+ value = element.text_content().strip()
+ selection = column.reify(cr, uid, model, column, context=context)
+ for k, v in selection:
+ if isinstance(v, str):
+ v = ustr(v)
+ if value == v:
+ return k
+
+ raise ValueError(u"No value found for label %s in selection %s" % (
+ value, selection))
+
class ManyToOne(orm.AbstractModel):
_name = 'website.qweb.field.many2one'
_inherit = ['website.qweb.field', 'ir.qweb.field.many2one']
+ def from_html(self, cr, uid, model, column, element, context=None):
+ # FIXME: this behavior is really weird, what if the user wanted to edit the name of the related thingy? Should m2os really be editable without a widget?
+ matches = self.pool[column._obj].name_search(
+ cr, uid, name=element.text_content().strip(), context=context)
+ # FIXME: no match? More than 1 match?
+ assert len(matches) == 1
+ return matches[0][0]
+
class HTML(orm.AbstractModel):
_name = 'website.qweb.field.html'
_inherit = ['website.qweb.field', 'ir.qweb.field.html']
+ def from_html(self, cr, uid, model, column, element, context=None):
+ content = []
+ if element.text: content.append(element.text)
+ content.extend(html.tostring(child)
+ for child in element.iterchildren(tag=etree.Element))
+ return '\n'.join(content)
+
+
class Image(orm.AbstractModel):
"""
Widget options:
--- /dev/null
+# -*- coding: utf-8 -*-
+from openerp.osv import orm, fields
+
+class test_converter(orm.Model):
+ _name = 'website.converter.test'
+
+ _columns = {
+ 'char': fields.char(),
+ 'integer': fields.integer(),
+ 'float': fields.float(),
+ 'numeric': fields.float(digits=(16, 2)),
+ 'many2one': fields.many2one('website.converter.test.sub'),
+ 'binary': fields.binary(),
+ 'date': fields.date(),
+ 'datetime': fields.datetime(),
+ 'selection': fields.selection([
+ (1, "réponse A"),
+ (2, "réponse B"),
+ (3, "réponse C"),
+ (4, "réponse D"),
+ ]),
+ 'selection_str': fields.selection([
+ ('A', "Qu'il n'est pas arrivé à Toronto"),
+ ('B', "Qu'il était supposé arriver à Toronto"),
+ ('C', "Qu'est-ce qu'il fout ce maudit pancake, tabernacle ?"),
+ ('D', "La réponse D"),
+ ], string="Lorsqu'un pancake prend l'avion à destination de Toronto et "
+ "qu'il fait une escale technique à St Claude, on dit:"),
+ 'html': fields.html(),
+ 'text': fields.text(),
+ }
+
+
+class test_converter_sub(orm.Model):
+ _name = 'website.converter.test.sub'
+
+ _columns = {
+ 'name': fields.char(),
+ }
field = el.get('data-oe-field')
column = Model._all_columns[field].column
- convert = self.pool['ir.fields.converter'].to_field(
- cr, uid, Model, column, fromtype="html", context=context)
- value, warnings = convert(el)
- # FIXME: report error
- if warnings: return
+ converter = self.pool['website.qweb'].get_converter_for(
+ el.get('data-oe-type'))
+ value = converter.from_html(cr, uid, Model, column, el)
Model.write(cr, uid, [int(el.get('data-oe-id'))], {
field: value
# -*- coding: utf-8 -*-
-from collections import namedtuple
from functools import partial
from xml.dom.minidom import getDOMImplementation
impl = getDOMImplementation()
document = impl.createDocument(None, None, None)
-Request = namedtuple('Request', 'cr uid registry')
-class RegistryProxy(object):
- def __init__(self, func):
- self.func = func
- def __getitem__(self, name):
- return self.func(name)
-
class TestConvertBack(common.TransactionCase):
def setUp(self):
super(TestConvertBack, self).setUp()
- self.Converter = self.registry('ir.fields.converter')
-
def field_rountrip_result(self, field, value, expected):
model = 'website.converter.test'
Model = self.registry(model)
field_value = 'record.%s' % field
e.setAttribute('t-field', field_value)
- rendered = self.registry('ir.qweb').render_tag_field(
+ rendered = self.registry('website.qweb').render_tag_field(
e, {'field': field_value}, '', {
'record': record,
})
rendered, parser=html.HTMLParser(encoding='utf-8'))
column = Model._all_columns[field].column
+ converter = self.registry('website.qweb').get_converter_for(
+ element.get('data-oe-type'))
- from_html = self.Converter.to_field(
- self.cr, self.uid, model, column, 'html')
-
- value_back, warnings = from_html(element)
- self.assertEqual(warnings, [])
+ value_back = converter.from_html(
+ self.cr, self.uid, model, column, element)
if isinstance(expected, str):
expected = expected.decode('utf-8')
h.H3("Column 2"),
h.UL(
h.LI("Item 1"),
- h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name'))),
- h.LI(h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone')))
+ h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name', type='char'))),
+ h.LI(h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone', type='char')))
))
)
self.view_id = self.registry('ir.ui.view').create(self.cr, self.uid, {
self.cr, self.uid, self.arch, context=None)
expect = [
- h.SPAN("My Company", attrs(model='res.company', id=1, field='name')),
- h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone')),
+ h.SPAN("My Company", attrs(model='res.company', id=1, field='name', type='char')),
+ h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone', type='char')),
]
for actual, expected in itertools.izip_longest(fields, expect):
self.eq(actual, expected)
def test_embedded_save(self):
- embedded = h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone'))
+ embedded = h.SPAN("+00 00 000 00 0 000", attrs(
+ model='res.company', id=1, field='phone', type='char'))
self.registry('ir.ui.view').save_embedded_field(self.cr, self.uid, embedded)
h.H3("Column 2"),
h.UL(
h.LI("Item 1"),
- h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name'))),
- h.LI(h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone')))
+ h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name', type='char'))),
+ h.LI(h.SPAN("+00 00 000 00 0 000", attrs(model='res.company', id=1, field='phone', type='char')))
))
))
h.H3("Column 2"),
h.UL(
h.LI("wob wob wob"),
- h.LI(h.SPAN("Acme Corporation", attrs(model='res.company', id=1, field='name', expression="bob"))),
- h.LI(h.SPAN("+12 3456789", attrs(model='res.company', id=1, field='phone', expression="edmund"))),
+ h.LI(h.SPAN("Acme Corporation", attrs(model='res.company', id=1, field='name', expression="bob", type='char'))),
+ h.LI(h.SPAN("+12 3456789", attrs(model='res.company', id=1, field='phone', expression="edmund", type='char'))),
)
), encoding='utf-8')
View.save(self.cr, self.uid, res_id=self.view_id, value=replacement,
node = html.tostring(h.SPAN(
"Acme Corporation",
- attrs(model='res.company', id=company_id, field="name", expression='bob')))
+ attrs(model='res.company', id=company_id, field="name", expression='bob', type='char')))
self.registry('ir.ui.view').save(self.cr, self.uid, res_id=company_id,value=node)
def test_field_tail(self):
View = self.registry('ir.ui.view')
replacement = ET.tostring(
- h.LI(h.SPAN("+12 3456789", attrs(model='res.company', id=1, field='phone', expression="edmund")),
+ h.LI(h.SPAN("+12 3456789", attrs(
+ model='res.company', id=1, type='char',
+ field='phone', expression="edmund")),
"whop whop"
), encoding="utf-8")
View.save(self.cr, self.uid, res_id = self.view_id, value=replacement,
h.H3("Column 2"),
h.UL(
h.LI("Item 1"),
- h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name'))),
+ h.LI(h.SPAN("My Company", attrs(model='res.company', id=1, field='name', type='char'))),
h.LI(h.SPAN({'t-field': "edmund"}), "whop whop"),
))
)