diff --git a/trytond/ir/ui/menu.py b/trytond/ir/ui/menu.py
index 4e722030e5..74a58fb76d 100644
--- a/trytond/ir/ui/menu.py
+++ b/trytond/ir/ui/menu.py
@@ -58,6 +58,7 @@ CLIENT_ICONS = [(x, x) for x in (
'tryton-system',
'tryton-undo',
'tryton-web-browser')]
+SEPARATOR = ' / '
class UIMenu(ModelSQL, ModelView):
@@ -72,7 +73,7 @@ class UIMenu(ModelSQL, ModelView):
groups = fields.Many2Many('ir.ui.menu-res.group',
'menu_id', 'gid', 'Groups')
complete_name = fields.Function(fields.Char('Complete Name',
- order_field='name'), 'get_full_name')
+ order_field='name'), 'get_rec_name', searcher='search_rec_name')
icon = fields.Selection('list_icons', 'Icon')
action = fields.Function(fields.Reference('Action',
selection=[
@@ -86,6 +87,14 @@ class UIMenu(ModelSQL, ModelView):
def __init__(self):
super(UIMenu, self).__init__()
self._order.insert(0, ('sequence', 'ASC'))
+ self._constraints += [
+ ('check_recursion', 'recursive_menu'),
+ ('check_name', 'wrong_name'),
+ ]
+ self._error_messages.update({
+ 'recursive_menu': 'You can not create recursive menu!',
+ 'wrong_name': 'You can not use "%s" in name field!' % SEPARATOR,
+ })
def default_icon(self):
return 'tryton-open'
@@ -101,20 +110,40 @@ class UIMenu(ModelSQL, ModelView):
return sorted(CLIENT_ICONS
+ [(name, name) for _, name in icon_obj.list_icons()])
- def get_full_name(self, ids, name):
- res = {}
+ def check_name(self, ids):
for menu in self.browse(ids):
- res[menu.id] = self._get_one_full_name(menu)
+ if SEPARATOR in menu.name:
+ return False
+ return True
+
+ def get_rec_name(self, ids, name):
+ if not ids:
+ return {}
+ res = {}
+ def _name(menu):
+ if menu.id in res:
+ return res[menu.id]
+ elif menu.parent:
+ return _name(menu.parent) + SEPARATOR + menu.name
+ else:
+ return menu.name
+ for menu in self.browse(ids):
+ res[menu.id] = _name(menu)
return res
- def _get_one_full_name(self, menu, level=6):
- if level <= 0:
- return '...'
- if menu.parent:
- parent_path = self._get_one_full_name(menu.parent, level-1) + "/"
- else:
- parent_path = ''
- return parent_path + menu.name
+ def search_rec_name(self, name, clause):
+ if isinstance(clause[2], basestring):
+ values = clause[2].split(SEPARATOR)
+ values.reverse()
+ domain = []
+ field = 'name'
+ for name in values:
+ domain.append((field, clause[1], name))
+ field = 'parent.' + field
+ ids = self.search(domain, order=[])
+ return [('id', 'in', ids)]
+ #TODO Handle list
+ return [('name',) + tuple(clause[1:])]
def search(self, domain, offset=0, limit=None, order=None, count=False,
query_string=False):
diff --git a/trytond/ir/ui/menu.xml b/trytond/ir/ui/menu.xml
index 2fce697e32..c9db9ab078 100644
--- a/trytond/ir/ui/menu.xml
+++ b/trytond/ir/ui/menu.xml
@@ -24,7 +24,7 @@ this repository contains the full copyright notices and license terms. -->
-
+
]]>
@@ -68,14 +68,25 @@ this repository contains the full copyright notices and license terms. -->
+
+
+
+ action="act_menu_list" id="menu_menu_list"/>
diff --git a/trytond/res/ir.xml b/trytond/res/ir.xml
index dffc554f0f..02ad948c85 100644
--- a/trytond/res/ir.xml
+++ b/trytond/res/ir.xml
@@ -444,7 +444,7 @@ this repository contains the full copyright notices and license terms. -->
-