[ADD] pagebreak to core qweb

This commit is contained in:
xmo-odoo
2018-07-25 16:53:11 +02:00
committed by GitHub
parent 369286d303
commit abc1289a4c
3 changed files with 113 additions and 3 deletions
+33 -1
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from __future__ import print_function
import ast
import copy
import json
import logging
from collections import OrderedDict
@@ -54,7 +55,38 @@ class IrQWeb(models.AbstractModel, QWeb):
context = dict(self.env.context, dev_mode='qweb' in tools.config['dev_mode'])
context.update(options)
return super(IrQWeb, self).render(id_or_xml_id, values=values, **context)
result = super(IrQWeb, self).render(id_or_xml_id, values=values, **context)
if b'data-pagebreak=' not in result:
return result
fragments = html.fragments_fromstring(result)
for fragment in fragments:
for row in fragment.iterfind('.//tr[@data-pagebreak]'):
table = next(row.iterancestors('table'))
newtable = html.Element('table', attrib=dict(table.attrib))
thead = table.find('thead')
if thead:
newtable.append(copy.deepcopy(thead))
# TODO: copy caption & tfoot as well?
# TODO: move rows in a tbody if row.getparent() is one?
pos = row.get('data-pagebreak')
assert pos in ('before', 'after')
for sibling in row.getparent().iterchildren('tr'):
if sibling is row:
if pos == 'after':
newtable.append(sibling)
break
newtable.append(sibling)
table.addprevious(newtable)
table.addprevious(html.Element('div', attrib={
'style': 'page-break-after: always'
}))
return b''.join(html.tostring(f) for f in fragments)
def default_values(self):
""" attributes add to the values for each computed template
+77 -1
View File
@@ -7,7 +7,8 @@ import os.path
import re
import sys
from lxml import etree
from lxml import etree, html
from lxml.builder import E
from odoo.modules import get_module_resource
from odoo.tests.common import TransactionCase
@@ -555,6 +556,81 @@ class TestQWeb(TransactionCase):
template
)
class TestPageSplit(TransactionCase):
# need to explicitly assertTreesEqual because I guess it's registered for
# equality between _Element *or* HtmlElement but we're comparing a parsed
# HtmlElement and a convenience _Element
def test_split_before(self):
t = self.env['ir.ui.view'].create({
'name': 'test',
'type': 'qweb',
'arch_db': '''<t t-name='test'>
<div>
<table>
<tr></tr>
<tr data-pagebreak="before"></tr>
<tr></tr>
</table>
</div>
</t>
'''
})
rendered = html.fromstring(self.env['ir.qweb'].render(t.id))
ref = E.div(
E.table(E.tr()),
E.div({'style': 'page-break-after: always'}),
E.table(E.tr({'data-pagebreak': 'before'}), E.tr())
)
print(etree.tostring(rendered))
print(etree.tostring(ref))
self.assertTreesEqual(rendered, ref)
def test_split_after(self):
t = self.env['ir.ui.view'].create({
'name': 'test',
'type': 'qweb',
'arch_db': '''<t t-name='test'>
<div>
<table>
<tr></tr>
<tr data-pagebreak="after"></tr>
<tr></tr>
</table>
</div>
</t>
'''
})
rendered = html.fromstring(self.env['ir.qweb'].render(t.id))
self.assertTreesEqual(
rendered,
E.div(
E.table(E.tr(), E.tr({'data-pagebreak': 'after'})),
E.div({'style': 'page-break-after: always'}),
E.table(E.tr())
)
)
def test_dontsplit(self):
t = self.env['ir.ui.view'].create({
'name': 'test',
'type': 'qweb',
'arch_db': '''<t t-name='test'>
<div>
<table>
<tr></tr>
<tr></tr>
<tr></tr>
</table>
</div>
</t>
'''
})
rendered = html.fromstring(self.env['ir.qweb'].render(t.id))
self.assertTreesEqual(
rendered,
E.div(E.table(E.tr(), E.tr(), E.tr()))
)
def load_tests(loader, suite, _):
# can't override TestQWeb.__dir__ because dir() called on *class* not
# instance
+3 -1
View File
@@ -107,6 +107,8 @@ class TreeCase(unittest.TestCase):
self.addTypeEqualityFunc(html.HtmlElement, self.assertTreesEqual)
def assertTreesEqual(self, n1, n2, msg=None):
self.assertIsNotNone(n1, msg)
self.assertIsNotNone(n2, msg)
self.assertEqual(n1.tag, n2.tag, msg)
# Because lxml.attrib is an ordereddict for which order is important
# to equality, even though *we* don't care
@@ -116,7 +118,7 @@ class TreeCase(unittest.TestCase):
self.assertEqual((n1.tail or u'').strip(), (n2.tail or u'').strip(), msg)
for c1, c2 in izip_longest(n1, n2):
self.assertEqual(c1, c2, msg)
self.assertTreesEqual(c1, c2, msg)
class MetaCase(type):