Commit e3aa1151 authored by Cédric Krier's avatar Cédric Krier
Browse files

Use `&` and `|` as boolean operator in search widget

Closes #11962, #8714
parent 802cca4584ee
Pipeline #61577 passed with stages
in 20 minutes and 22 seconds
* Use ``&`` and ``|`` as boolean operator in search widget
* Use toggle button and label on translate dialog
* Support border type of images
* Manage domain on id in single value list as unique
......
......@@ -1306,7 +1306,7 @@
var nary = ' ';
if ((domain[0] == 'AND') || (domain[0] == 'OR')) {
if (domain[0] == 'OR') {
nary = ' or ';
nary = ' | ';
}
domain = domain.slice(1);
}
......@@ -1729,5 +1729,6 @@
var result = [];
operator = operator || 'or';
tokens = jQuery.extend([], tokens);
var notation = {'or': '|', 'and': '&'}[operator];
var test = function(value) {
if (value instanceof Array) {
......@@ -1732,4 +1733,4 @@
var test = function(value) {
if (value instanceof Array) {
return Sao.common.compare(value, [operator]);
return Sao.common.compare(value, [notation]);
} else {
......@@ -1735,5 +1736,5 @@
} else {
return value == operator;
return value == notation;
}
};
var cur = tokens.shift();
......
......@@ -1578,9 +1578,9 @@
[
[['a'], ['a']],
[['a', 'or', 'b'], [['OR', 'a', 'b']]],
[['a', 'or', 'b', 'or', 'c'], [['OR', ['OR', 'a', 'b'], 'c']]],
[['a', 'b', 'or', 'c'], ['a', ['OR', 'b', 'c']]],
[['a', 'or', 'b', 'c'], [['OR', 'a', 'b'], 'c']],
[['a', '|', 'b'], [['OR', 'a', 'b']]],
[['a', '|', 'b', '|', 'c'], [['OR', ['OR', 'a', 'b'], 'c']]],
[['a', 'b', '|', 'c'], ['a', ['OR', 'b', 'c']]],
[['a', '|', 'b', 'c'], [['OR', 'a', 'b'], 'c']],
[['a', ['b', 'c']], ['a', ['b', 'c']]],
[['a', ['b', 'c'], 'd'], ['a', ['b', 'c'], 'd']],
......@@ -1585,5 +1585,5 @@
[['a', ['b', 'c']], ['a', ['b', 'c']]],
[['a', ['b', 'c'], 'd'], ['a', ['b', 'c'], 'd']],
[['a', 'or', ['b', 'c']], [['OR', 'a', ['b', 'c']]]],
[['a', 'or', ['b', 'c'], 'd'],
[['a', '|', ['b', 'c']], [['OR', 'a', ['b', 'c']]]],
[['a', '|', ['b', 'c'], 'd'],
[['OR', 'a', ['b', 'c']], 'd']],
......@@ -1589,3 +1589,3 @@
[['OR', 'a', ['b', 'c']], 'd']],
[['a', ['b', 'c'], 'or', 'd'],
[['a', ['b', 'c'], '|', 'd'],
['a', ['OR', ['b', 'c'], 'd']]],
......@@ -1591,3 +1591,3 @@
['a', ['OR', ['b', 'c'], 'd']]],
[['a', 'or', ['b', 'or', 'c']],
[['a', '|', ['b', '|', 'c']],
[['OR', 'a', [['OR', 'b', 'c']]]]],
......@@ -1593,12 +1593,12 @@
[['OR', 'a', [['OR', 'b', 'c']]]]],
[['or'], []],
[['or', 'a'], ['a']],
[['a', ['or', 'b']], ['a', ['b']]],
[['a', 'or', 'or', 'b'], [['OR', 'a', 'b']]],
[['or', 'or', 'a'], ['a']],
[['or', 'or', 'a', 'b'], ['a', 'b']],
[['or', 'or', 'a', 'or', 'b'], [['OR', 'a', 'b']]],
[['a', ['b', 'or', 'c']], ['a', [['OR', 'b', 'c']]]],
[[a, [b, ['or'], c]], [a, [['OR', b, c]]]],
[['a', ['b', 'or']], ['a', [['OR', 'b']]]],
[['|'], []],
[['|', 'a'], ['a']],
[['a', ['|', 'b']], ['a', ['b']]],
[['a', '|', '|', 'b'], [['OR', 'a', 'b']]],
[['|', '|', 'a'], ['a']],
[['|', '|', 'a', 'b'], ['a', 'b']],
[['|', '|', 'a', '|', 'b'], [['OR', 'a', 'b']]],
[['a', ['b', '|', 'c']], ['a', [['OR', 'b', 'c']]]],
[[a, [b, ['|'], c]], [a, [['OR', b, c]]]],
[['a', ['b', '|']], ['a', [['OR', 'b']]]],
[[null_], [null_]],
......@@ -1604,5 +1604,5 @@
[[null_], [null_]],
[[null_, 'or', double_null_], [['OR', null_, double_null_]]]
[[null_, '|', double_null_], [['OR', null_, double_null_]]]
].forEach(function(test) {
var value = test[0];
var result = test[1];
......@@ -2233,10 +2233,10 @@
[['OR',
['name', 'ilike', '%Doe%'],
['name', 'ilike', '%Jane%']
], 'Name: Doe or Name: Jane'],
], 'Name: Doe | Name: Jane'],
[[
['name', 'ilike', '%Doe%'],
['OR',
['name', 'ilike', '%John%'],
['name', 'ilike', '%Jane%']
]
......@@ -2237,10 +2237,10 @@
[[
['name', 'ilike', '%Doe%'],
['OR',
['name', 'ilike', '%John%'],
['name', 'ilike', '%Jane%']
]
], 'Name: Doe (Name: John or Name: Jane)'],
], 'Name: Doe (Name: John | Name: Jane)'],
[[], ''],
[[['surname', 'ilike', '%Doe%']], '"(Sur)Name": Doe'],
//[[['date', '>=', new Date(2012, 10, 24)]], 'Date: >=10/24/2012'],
......@@ -3112,8 +3112,8 @@
['Name: !=foo', []],
['', ["Name: "]],
[' ', ["", "Name: "]],
["Name: foo or", ["Name: foo"]],
['Name: foo (Name: foo or N', ["Name: foo (Name: foo or Name: "]],
["Name: foo |", ["Name: foo"]],
['Name: foo (Name: foo | N', ["Name: foo (Name: foo | Name: "]],
].forEach(function(test) {
var value = test[0];
var expected = test[1];
......
* Use ``&`` and ``|`` as boolean operator in search widget
* Use toggle button and label on translate dialog
* Manage domain on id in single value list as unique
* Do not validate domain and enforce uniqueness for empty fields unless they're required
......
......@@ -512,9 +512,10 @@
Clause composition
++++++++++++++++++
The clauses can be composed using the two boolean operators ``and`` and ``or``.
By default, there is an implicit ``and`` between each clause if no operator is
The clauses can be composed using the two boolean operators ``&`` (for `logical
conjunction`_) and ``|`` (for `logical disjunction`_).
By default, there is an implicit ``&`` between each clause if no operator is
specified.
For example: ``Name: Michael Amount: 100``
......@@ -517,6 +518,6 @@
specified.
For example: ``Name: Michael Amount: 100``
is the same as ``Name: Michael and Amount: 100``
is the same as ``Name: Michael & Amount: 100``
......@@ -522,4 +523,6 @@
The ``and`` operator has a highest precedence than ``or`` but you can change it
by using parenthesis.
The ``&`` operator has a highest precedence than ``|`` but you can change it by
using parenthesis.
For example: ``(Name: Michael | Name: Pam) & Amount: 100``
......@@ -525,3 +528,3 @@
For example: ``(Name: Michael or Name: Pam) and Amount: 100``
is different than ``Name: Michael | Name: Pam & Amount: 100``
......@@ -527,3 +530,3 @@
is different than ``Name: Michael or Name: Pam and Amount: 100``
which is evaluated as ``Name: Michael | (Name: Pam & Amount: 100)``
......@@ -529,5 +532,6 @@
which is evaluated as ``Name: Michael or (Name: Pam and Amount: 100)``
.. _logical conjunction: https://en.wikipedia.org/wiki/Logical_conjunction
.. _logical disjunction: https://en.wikipedia.org/wiki/Logical_disjunction
RichText Editor
^^^^^^^^^^^^^^^
......
......@@ -484,7 +484,10 @@
def operatorize(tokens, operator='or'):
"Convert operators"
test = (operator, (operator,))
test = {
'or': ('|', ('|',)),
'and': ('&', ('&',)),
}[operator]
try:
cur = next(tokens)
while cur in test:
......@@ -656,7 +659,7 @@
if not domain:
return ''
if domain[0] in ('AND', 'OR'):
nary = ' ' if domain[0] == 'AND' else ' or '
nary = ' ' if domain[0] == 'AND' else ' | '
domain = domain[1:]
else:
nary = ' '
......
......@@ -529,9 +529,9 @@
double_null_ = ('e', None, None)
for value, result in (
(['a'], ['a']),
(['a', 'or', 'b'], [['OR', 'a', 'b']]),
(['a', 'or', 'b', 'or', 'c'], [['OR', ['OR', 'a', 'b'], 'c']]),
(['a', 'b', 'or', 'c'], ['a', ['OR', 'b', 'c']]),
(['a', 'or', 'b', 'c'], [['OR', 'a', 'b'], 'c']),
(['a', '|', 'b'], [['OR', 'a', 'b']]),
(['a', '|', 'b', '|', 'c'], [['OR', ['OR', 'a', 'b'], 'c']]),
(['a', 'b', '|', 'c'], ['a', ['OR', 'b', 'c']]),
(['a', '|', 'b', 'c'], [['OR', 'a', 'b'], 'c']),
(['a', iter(['b', 'c'])], ['a', ['b', 'c']]),
(['a', iter(['b', 'c']), 'd'], ['a', ['b', 'c'], 'd']),
......@@ -536,5 +536,5 @@
(['a', iter(['b', 'c'])], ['a', ['b', 'c']]),
(['a', iter(['b', 'c']), 'd'], ['a', ['b', 'c'], 'd']),
(['a', 'or', iter(['b', 'c'])], [['OR', 'a', ['b', 'c']]]),
(['a', 'or', iter(['b', 'c']), 'd'],
(['a', '|', iter(['b', 'c'])], [['OR', 'a', ['b', 'c']]]),
(['a', '|', iter(['b', 'c']), 'd'],
[['OR', 'a', ['b', 'c']], 'd']),
......@@ -540,3 +540,3 @@
[['OR', 'a', ['b', 'c']], 'd']),
(['a', iter(['b', 'c']), 'or', 'd'],
(['a', iter(['b', 'c']), '|', 'd'],
['a', ['OR', ['b', 'c'], 'd']]),
......@@ -542,3 +542,3 @@
['a', ['OR', ['b', 'c'], 'd']]),
(['a', 'or', iter(['b', 'or', 'c'])],
(['a', '|', iter(['b', '|', 'c'])],
[['OR', 'a', [['OR', 'b', 'c']]]]),
......@@ -544,12 +544,12 @@
[['OR', 'a', [['OR', 'b', 'c']]]]),
(['or'], []),
(['or', 'a'], ['a']),
(['a', iter(['or', 'b'])], ['a', ['b']]),
(['a', 'or', 'or', 'b'], [['OR', 'a', 'b']]),
(['or', 'or', 'a'], ['a']),
(['or', 'or', 'a', 'b'], ['a', 'b']),
(['or', 'or', 'a', 'or', 'b'], [['OR', 'a', 'b']]),
(['a', iter(['b', 'or', 'c'])], ['a', [['OR', 'b', 'c']]]),
([a, iter([b, ('or',), c])], [a, [['OR', b, c]]]),
(['a', iter(['b', 'or'])], ['a', [['OR', 'b']]]),
(['|'], []),
(['|', 'a'], ['a']),
(['a', iter(['|', 'b'])], ['a', ['b']]),
(['a', '|', '|', 'b'], [['OR', 'a', 'b']]),
(['|', '|', 'a'], ['a']),
(['|', '|', 'a', 'b'], ['a', 'b']),
(['|', '|', 'a', '|', 'b'], [['OR', 'a', 'b']]),
(['a', iter(['b', '|', 'c'])], ['a', [['OR', 'b', 'c']]]),
([a, iter([b, ('|',), c])], [a, [['OR', b, c]]]),
(['a', iter(['b', '|'])], ['a', [['OR', 'b']]]),
([null_], [null_]),
......@@ -555,5 +555,5 @@
([null_], [null_]),
([null_, 'or', double_null_], [['OR', null_, double_null_]]),
([null_, '|', double_null_], [['OR', null_, double_null_]]),
):
self.assertEqual(
rlist(operatorize(iter(value))), result,
......@@ -696,10 +696,10 @@
dom.string(['OR',
('name', 'ilike', '%Doe%'),
('name', 'ilike', '%Jane%')]),
'Name: Doe or Name: Jane')
'Name: Doe | Name: Jane')
self.assertEqual(
dom.string([
('name', 'ilike', '%Doe%'),
['OR',
('name', 'ilike', '%John%'),
('name', 'ilike', '%Jane%')]]),
......@@ -700,10 +700,10 @@
self.assertEqual(
dom.string([
('name', 'ilike', '%Doe%'),
['OR',
('name', 'ilike', '%John%'),
('name', 'ilike', '%Jane%')]]),
'Name: Doe (Name: John or Name: Jane)')
'Name: Doe (Name: John | Name: Jane)')
self.assertEqual(dom.string([]), '')
self.assertEqual(
dom.string([('surname', 'ilike', '%Doe%')]), '"(Sur)Name": Doe')
......@@ -1121,5 +1121,5 @@
self.assertEqual(list(dom.completion('Name: !=foo')), [])
self.assertEqual(list(dom.completion('')), ['Name: '])
self.assertEqual(list(dom.completion(' ')), ['', 'Name: '])
self.assertEqual(list(dom.completion('Name: foo or')), ['Name: foo'])
self.assertEqual(list(dom.completion('Name: foo |')), ['Name: foo'])
self.assertEqual(
......@@ -1125,6 +1125,6 @@
self.assertEqual(
list(dom.completion('Name: foo (Name: foo or N')),
['Name: foo (Name: foo or Name: '])
list(dom.completion('Name: foo (Name: foo | N')),
['Name: foo (Name: foo | Name: '])
def test_completion_many2one(self):
"Test completion many2one"
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment