From 9f4db88bdf0d21acead3f6e33660ec9fad16ab84 Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Mon, 20 Sep 2010 11:33:54 +0200 Subject: [PATCH] Wrong index type for selection strings that are not multivalued. --- gen/__init__.py | 5 +++-- gen/layout.py | 6 ++++-- gen/plone25/installer.py | 3 ++- gen/plone25/mixins/ToolMixin.py | 28 ++++++++++++++++++-------- gen/plone25/mixins/__init__.py | 6 +----- gen/plone25/skin/macros.pt | 6 +++--- gen/plone25/skin/portlet.pt | 13 ++++++------ gen/plone25/skin/widgets/ref.pt | 2 +- gen/plone25/wrappers/FlavourWrapper.py | 2 +- 9 files changed, 41 insertions(+), 30 deletions(-) diff --git a/gen/__init__.py b/gen/__init__.py index 87177be..6ff1c3d 100644 --- a/gen/__init__.py +++ b/gen/__init__.py @@ -402,11 +402,12 @@ class Type: res = True return res - def isSortable(self, usage='search'): + def isSortable(self, usage): '''Can fields of this type be used for sorting purposes (when sorting search results (p_usage="search") or when sorting reference fields (p_usage="ref")?''' - if usage == 'search': return self.indexed + if usage == 'search': + return self.indexed and not self.isMultiValued() elif usage == 'ref': return self.type in ('Integer', 'Float', 'Boolean', 'Date') or \ ((self.type == 'String') and (self.format == 0)) diff --git a/gen/layout.py b/gen/layout.py index d2e2613..f4d1eef 100644 --- a/gen/layout.py +++ b/gen/layout.py @@ -120,7 +120,7 @@ class Table(LayoutElement): '''Represents a table where to dispose graphical elements.''' simpleParams = ('style', 'css_class', 'cellpadding', 'cellspacing', 'width', 'align') - derivedRepls = {'view': 'hrv', 'cell': 'l'} + derivedRepls = {'view': 'hrv', 'cell': 'ld'} def __init__(self, layoutString=None, style=None, css_class='', cellpadding=0, cellspacing=0, width='100%', align='left', other=None, derivedType=None): @@ -191,7 +191,9 @@ class Table(LayoutElement): if char in rowDelimiters: valign = rowDelimiters[char] if self.isHeaderRow(rowContent): - self.headerRow = Row(rowContent,valign,isHeader=True).get() + if not self.headerRow: + self.headerRow = Row(rowContent, valign, + isHeader=True).get() else: self.rows.append(Row(rowContent, valign).get()) rowContent = '' diff --git a/gen/plone25/installer.py b/gen/plone25/installer.py index b9bdec3..b8d0bd8 100644 --- a/gen/plone25/installer.py +++ b/gen/plone25/installer.py @@ -451,7 +451,8 @@ class PloneInstaller: n = appyType.name indexName = 'get%s%s' % (n[0].upper(), n[1:]) indexType = 'FieldIndex' - if (appyType.type == 'String') and appyType.isSelect: + if (appyType.type == 'String') and appyType.isSelect and \ + appyType.isMultiValued(): indexType = 'ZCTextIndex' indexInfo[indexName] = indexType if indexInfo: diff --git a/gen/plone25/mixins/ToolMixin.py b/gen/plone25/mixins/ToolMixin.py index da3332e..bdc5626 100644 --- a/gen/plone25/mixins/ToolMixin.py +++ b/gen/plone25/mixins/ToolMixin.py @@ -275,6 +275,14 @@ class ToolMixin(AbstractMixin): return value[:maxWidth] + '...' return value + def truncateText(self, text, width=15): + '''Truncates p_text to max p_width chars. If the text is longer than + p_width, the truncated part is put in a "acronym" html tag.''' + if len(text) <= width: return text + else: + return '%s' % \ + (text, text[:width] + '...') + translationMapping = {'portal_path': ''} def translateWithMapping(self, label): '''Translates p_label in the application domain, with a default @@ -336,15 +344,13 @@ class ToolMixin(AbstractMixin): res[means.id] = means.__dict__ return res - def userMayAdd(self, rootClass): - '''For deciding if a user may add a new instance of a class, beyond the - permission-based check, we can have a custom method that proposes an - additional condition. This method checks if there is such a custom - method (must be named "mayCreate") define on p_rootClass, and calls - it if yes. If no, it returns True.''' + def userMaySearch(self, rootClass): + '''This method checks if the currently logged user can trigger searches + on a given p_rootClass. This is done by calling method "maySearch" + on the class. If no such method exists, we return True.''' pythonClass = self.getAppyClass(rootClass) - if 'mayCreate' in pythonClass.__dict__: - return pythonClass.mayCreate(self.appy()) + if 'maySearch' in pythonClass.__dict__: + return pythonClass.maySearch(self.appy()) return True def onImportObjects(self): @@ -369,6 +375,12 @@ class ToolMixin(AbstractMixin): else: return False + def isSortable(self, name, className, usage): + '''Is field p_name defined on p_metaType sortable for p_usage purposes + (p_usage can be "ref" or "search")?''' + appyType = self.getAppyType(name, className=className) + return appyType.isSortable(usage=usage) + def _searchValueIsEmpty(self, key): '''Returns True if request value in key p_key can be considered as empty.''' diff --git a/gen/plone25/mixins/__init__.py b/gen/plone25/mixins/__init__.py index 0e02741..c461f7e 100644 --- a/gen/plone25/mixins/__init__.py +++ b/gen/plone25/mixins/__init__.py @@ -642,11 +642,6 @@ class AbstractMixin: reverse = rq.get('reverse') == 'True' self.appy().sort(fieldName, sortKey=sortKey, reverse=reverse) - def isRefSortable(self, fieldName): - '''Can p_fieldName, which is a field defined on self, be used as a sort - key in a reference field?''' - return self.getAppyType(fieldName).isSortable(usage='ref') - def getWorkflow(self, appy=True): '''Returns the Appy workflow instance that is relevant for this object. If p_appy is False, it returns the DC workflow.''' @@ -969,6 +964,7 @@ class AbstractMixin: if created and rq.get('nav', None): # Get the initiator splitted = rq['nav'].split('.') + if splitted[0] == 'search': return # Not an initiator but a search. initiator = self.uid_catalog.searchResults( UID=splitted[1])[0].getObject() fieldName = splitted[2].split(':')[1] diff --git a/gen/plone25/skin/macros.pt b/gen/plone25/skin/macros.pt index 70a6779..53f4cc9 100644 --- a/gen/plone25/skin/macros.pt +++ b/gen/plone25/skin/macros.pt @@ -54,18 +54,18 @@ Mandatory column "Title"/"Name" - + Columns corresponding to other fields Display header for a "standard" field - + Display header for the workflow state diff --git a/gen/plone25/skin/portlet.pt b/gen/plone25/skin/portlet.pt index 59e58a3..48ae628 100644 --- a/gen/plone25/skin/portlet.pt +++ b/gen/plone25/skin/portlet.pt @@ -12,11 +12,11 @@ title allows to see all root objects in the database. -
- + - @@ -35,15 +35,14 @@
- - TODO: implement a widget for selecting the needed flavour. Create a section for every root class. Section title, with action icons -
+
@@ -53,7 +52,7 @@ Create a new object from a web form + tal:define="ajaxBaseCall python: navBaseCall.replace('**v**', '\'%s\',\'SortReference\', {\'sortKey\':\'%s\', \'reverse\':\'**v**\'}' % (startNumber, shownField))" tal:condition="python: canWrite and tool.isSortable(shownField, objs[0].meta_type, 'ref')"> diff --git a/gen/plone25/wrappers/FlavourWrapper.py b/gen/plone25/wrappers/FlavourWrapper.py index 57a2c09..aa76fd9 100644 --- a/gen/plone25/wrappers/FlavourWrapper.py +++ b/gen/plone25/wrappers/FlavourWrapper.py @@ -46,7 +46,7 @@ class FlavourWrapper(AbstractWrapper): p_attrName. "resultColumns" - Stores the list of columns that must be show when displaying + Stores the list of columns that must be shown when displaying instances of the a given root p_klass. "enableAdvancedSearch"