From f398b77af5514fdfe75dda4c30089e02dcdb662d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9dric=20Krier?= Date: Fri, 18 Oct 2013 22:24:49 +0200 Subject: [PATCH] Add stringable on DomainParser It is possible to convert to string a domain only if all the fields are in the view. So bookmark must be filled with only stringable domains. issue3430 review1142002 --- tryton/common/domain_parser.py | 36 +++++++++++++++++++ .../window/view_form/view/screen_container.py | 16 +++++---- 2 files changed, 45 insertions(+), 7 deletions(-) diff --git a/tryton/common/domain_parser.py b/tryton/common/domain_parser.py index bbe8011820..e17be8d98a 100644 --- a/tryton/common/domain_parser.py +++ b/tryton/common/domain_parser.py @@ -747,6 +747,25 @@ class DomainParser(object): if exception.message == 'No closing quotation': return self.parse(input_ + '"') + def stringable(self, domain): + + def stringable_(clause): + if not clause: + return True + if (((clause[0] in ('AND', 'OR')) + or isinstance(clause[0], (list, tuple))) + and all(isinstance(c, (list, tuple)) for c in clause[1:])): + return self.stringable(clause) + if clause[0] in self.fields or clause[0] == 'rec_name': + return True + return False + + if not domain: + return True + if domain[0] in ('AND', 'OR'): + domain = domain[1:] + return all(stringable_(clause) for clause in domain) + def string(self, domain): "Return string for the domain" @@ -984,6 +1003,23 @@ class DomainParser(object): yield field['name'], operator, value +def test_stringable(): + dom = DomainParser({ + 'name': { + 'string': 'Name', + 'type': 'char', + }, + }) + valid = ('name', '=', 'Doe') + invalid = ('surname', '=', 'John') + assert dom.stringable([valid]) + assert not dom.stringable([invalid]) + assert dom.stringable(['AND', valid]) + assert not dom.stringable(['AND', valid, invalid]) + assert dom.stringable([[valid]]) + assert not dom.stringable([[valid], [invalid]]) + + def test_string(): dom = DomainParser({ 'name': { diff --git a/tryton/gui/window/view_form/view/screen_container.py b/tryton/gui/window/view_form/view/screen_container.py index 5d9449695b..ec17416bc6 100644 --- a/tryton/gui/window/view_form/view/screen_container.py +++ b/tryton/gui/window/view_form/view/screen_container.py @@ -133,8 +133,7 @@ class ScreenContainer(object): False ) - for id_, name, domain in common.VIEW_SEARCH[ - self.screen.model_name]: + for id_, name, domain in self.bookmarks(): menuitem = gtk.MenuItem(name) menuitem.connect('activate', self.bookmark_activate, domain) menu.add(menuitem) @@ -227,8 +226,7 @@ class ScreenContainer(object): def set_screen(self, screen): self.screen = screen - self.but_bookmark.set_sensitive( - bool(common.VIEW_SEARCH[screen.model_name])) + self.but_bookmark.set_sensitive(bool(list(self.bookmarks()))) self.bookmark_match() def show_filter(self): @@ -287,6 +285,11 @@ class ScreenContainer(object): self.search_entry.set_text(value) self.bookmark_match() + def bookmarks(self): + for id_, name, domain in common.VIEW_SEARCH[self.screen.model_name]: + if self.screen.domain_parser.stringable(domain): + yield id_, name, domain + def bookmark_activate(self, menuitem, domain): self.set_text(self.screen.domain_parser.string(domain)) self.do_search() @@ -299,7 +302,7 @@ class ScreenContainer(object): self.search_entry.set_icon_sensitive(gtk.ENTRY_ICON_SECONDARY, bool(current_text)) icon_stock = self.search_entry.get_icon_stock(gtk.ENTRY_ICON_SECONDARY) - for id_, name, domain in common.VIEW_SEARCH[self.screen.model_name]: + for id_, name, domain in self.bookmarks(): text = self.screen.domain_parser.string(domain) domain = self.screen.domain_parser.parse(text.decode('utf-8')) if (text == current_text @@ -385,8 +388,7 @@ class ScreenContainer(object): common.VIEW_SEARCH.remove(model_name, id_) # Refresh icon and bookmark button self.bookmark_match() - self.but_bookmark.set_sensitive( - bool(common.VIEW_SEARCH[model_name])) + self.but_bookmark.set_sensitive(bool(list(self.bookmarks()))) def focus_in(self, widget, event): self.update()