diff --git a/gen/__init__.py b/gen/__init__.py index 01d8675..e17e25f 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -298,7 +298,7 @@ class Import: class Search: '''Used for specifying a search for a given type.''' def __init__(self, name, group=None, sortBy='', sortOrder='asc', limit=None, - default=False, colspan=1, translated=None, + default=False, colspan=1, translated=None, show=True, translatedDescr=None, **fields): self.name = name # Searches may be visually grouped in the portlet. @@ -314,6 +314,8 @@ class Search: # use it instead of trying to translate from labels. self.translated = translated self.translatedDescr = translatedDescr + # Condition for showing or not this search + self.show = show # In the dict below, keys are indexed field names or names of standard # indexes, and values are search values. self.fields = fields @@ -331,6 +333,8 @@ class Search: # 'SortableTitle', because index 'Title' is a TextIndex # (for searchability) and can't be used for sorting. elif fieldName == 'state': return 'State' + elif fieldName == 'created': return 'Created' + elif fieldName == 'modified': return 'Modified' elif fieldName in defaultIndexes: return fieldName else: return 'get%s%s'% (fieldName[0].upper(),fieldName[1:]) @@ -403,6 +407,12 @@ class Search: criteria['sortBy'] = self.sortBy criteria['sortOrder'] = self.sortOrder + def isShowable(self, klass, tool): + '''Is this Search instance (defined in p_klass) showable?''' + if self.show.__class__.__name__ == 'staticmethod': + return self.show.__get__(klass)(tool) + return self.show + # ------------------------------------------------------------------------------ class Type: '''Basic abstract class for defining any appy type.''' diff --git a/gen/descriptors.py b/gen/descriptors.py index af19d58..cd1b2ea 100644 --- a/gen/descriptors.py +++ b/gen/descriptors.py @@ -174,35 +174,28 @@ class ClassDescriptor(Descriptor): def getCreateMean(self, type='Import'): '''Returns the mean for this class that corresponds to p_type, or None if the class does not support this create mean.''' - if not self.klass.__dict__.has_key('create'): return None + if not self.klass.__dict__.has_key('create'): return else: means = self.klass.create - if not means: return None + if not means: return if not isinstance(means, tuple) and not isinstance(means, list): means = [means] for mean in means: exec 'found = isinstance(mean, %s)' % type if found: return mean - return None @staticmethod - def getSearches(klass): - '''Returns the list of searches that are defined on this class.''' - res = [] + def getSearches(klass, tool=None): + '''Returns the list of searches that are defined on this class. If + p_tool is given, we are at execution time (not a generation time), + and we may potentially execute search.show methods that allow to + conditionnaly include a search or not.''' if klass.__dict__.has_key('search'): searches = klass.__dict__['search'] - if isinstance(searches, basestring): - res.append(gen.Search(searches)) - elif isinstance(searches, gen.Search): - res.append(searches) - else: - # It must be a list of searches. - for search in searches: - if isinstance(search, basestring): - res.append(gen.Search(search)) - else: - res.append(search) - return res + if not tool: return searches + # Evaluate attributes "show" for every search. + return [s for s in searches if s.isShowable(klass, tool)] + return [] @staticmethod def getSearch(klass, searchName): @@ -210,7 +203,6 @@ class ClassDescriptor(Descriptor): for search in ClassDescriptor.getSearches(klass): if search.name == searchName: return search - return None def addIndexMethod(self, field): '''For indexed p_field, this method generates a method that allows to diff --git a/gen/mixins/ToolMixin.py b/gen/mixins/ToolMixin.py index 68b6b41..020d1ff 100644 --- a/gen/mixins/ToolMixin.py +++ b/gen/mixins/ToolMixin.py @@ -723,22 +723,23 @@ class ToolMixin(BaseMixin): default = None # Also retrieve the default one here. groups = {} # The already encountered groups page = Page('main') # A dummy page required by class GroupDescr - searches = ClassDescriptor.getSearches(appyClass) - # Add dynamic searches if defined on p_appyClass + # Get the searches statically defined on the class + searches = ClassDescriptor.getSearches(appyClass, tool=self.appy()) + # Get the dynamically computed searches if hasattr(appyClass, 'getDynamicSearches'): searches += appyClass.getDynamicSearches(self.appy()) for search in searches: # Create the search descriptor - searchDescr = SearchDescr(search, className, self).get() + sDescr = SearchDescr(search, className, self).get() if not search.group: # Insert the search at the highest level, not in any group. - res.append(searchDescr) + res.append(sDescr) else: - groupDescr = search.group.insertInto(res, groups, page, - className, forSearch=True) - GroupDescr.addWidget(groupDescr, searchDescr) + gDescr = search.group.insertInto(res, groups, page, className, + forSearch=True) + GroupDescr.addWidget(gDescr, sDescr) # Is this search the default search? - if search.default: default = searchDescr + if search.default: default = sDescr return Object(searches=res, default=default).__dict__ def getSearch(self, className, name, descr=False): @@ -766,6 +767,15 @@ class ToolMixin(BaseMixin): if descr: res = SearchDescr(res, className, self).get() return res + def advancedSearchEnabledFor(self, className): + '''Is advanced search visible for p_klass ?''' + klass = self.getAppyClass(className) + # By default, advanced search is enabled. + if not hasattr(klass, 'searchAdvanced'): return True + # Evaluate attribute "show" on this Search instance representing the + # advanced search. + return klass.searchAdvanced.isShowable(klass, self.appy()) + def getQueryUrl(self, contentType, searchName, startNumber=None): '''This method creates the URL that allows to perform a (non-Ajax) request for getting queried objects from a search named p_searchName diff --git a/gen/ui/portlet.pt b/gen/ui/portlet.pt index 190c8fc..3b75217 100644 --- a/gen/ui/portlet.pt +++ b/gen/ui/portlet.pt @@ -90,7 +90,7 @@
- + Live search