2013-07-08 16:39:16 -05:00
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
# This file is part of Appy, a framework for building applications in the Python
|
|
|
|
# language. Copyright (C) 2007 Gaetan Delannay
|
|
|
|
|
|
|
|
# Appy is free software; you can redistribute it and/or modify it under the
|
|
|
|
# terms of the GNU General Public License as published by the Free Software
|
|
|
|
# Foundation; either version 3 of the License, or (at your option) any later
|
|
|
|
# version.
|
|
|
|
|
|
|
|
# Appy is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
|
|
|
|
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
|
|
|
|
|
|
|
|
# You should have received a copy of the GNU General Public License along with
|
|
|
|
# Appy. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
from appy.fields import Field
|
|
|
|
from appy.px import Px
|
|
|
|
|
|
|
|
# ------------------------------------------------------------------------------
|
|
|
|
class Computed(Field):
|
2014-02-27 13:03:39 -06:00
|
|
|
WRONG_METHOD = 'Wrong value "%s". Param "method" must contain a method ' \
|
|
|
|
'or a PX.'
|
2014-03-05 09:19:11 -06:00
|
|
|
pxView = pxCell = pxEdit = Px('''<x if="field.plainText">:value</x>
|
|
|
|
<x if="not field.plainText">::value</x>''')
|
2013-07-15 04:23:29 -05:00
|
|
|
|
2014-03-05 06:25:36 -06:00
|
|
|
pxSearch = Px('''
|
2014-05-17 09:44:56 -05:00
|
|
|
<input type="text" name=":'%s*string' % widgetName"
|
|
|
|
maxlength=":field.maxChars" size=":field.width"
|
|
|
|
value=":field.sdefault"/>''')
|
2013-07-08 16:39:16 -05:00
|
|
|
|
|
|
|
def __init__(self, validator=None, multiplicity=(0,1), default=None,
|
2014-12-08 07:52:04 -06:00
|
|
|
show=None, page='main', group=None, layouts=None, move=0,
|
|
|
|
indexed=False, searchable=False, specificReadPermission=False,
|
|
|
|
specificWritePermission=False, width=None, height=None,
|
|
|
|
maxChars=None, colspan=1, method=None, formatMethod=None,
|
|
|
|
plainText=False, master=None, masterValue=None, focus=False,
|
|
|
|
historized=False, mapping=None, label=None, sdefault='',
|
2014-12-09 08:19:28 -06:00
|
|
|
scolspan=1, swidth=None, sheight=None, context=None, view=None,
|
|
|
|
xml=None):
|
2013-09-20 10:42:07 -05:00
|
|
|
# The Python method used for computing the field value, or a PX.
|
2013-07-08 16:39:16 -05:00
|
|
|
self.method = method
|
2014-10-15 02:39:01 -05:00
|
|
|
# A specific method for producing the formatted value of this field.
|
|
|
|
# This way, if, for example, the value is a DateTime instance which is
|
|
|
|
# indexed, you can specify in m_formatMethod the way to format it in
|
|
|
|
# the user interface while m_method computes the value stored in the
|
|
|
|
# catalog.
|
|
|
|
self.formatMethod = formatMethod
|
2014-02-27 13:03:39 -06:00
|
|
|
if isinstance(self.method, basestring):
|
|
|
|
# A legacy macro identifier. Raise an exception
|
|
|
|
raise Exception(self.WRONG_METHOD % self.method)
|
2013-07-08 16:39:16 -05:00
|
|
|
# Does field computation produce plain text or XHTML?
|
|
|
|
self.plainText = plainText
|
2013-09-20 10:42:07 -05:00
|
|
|
if isinstance(method, Px):
|
|
|
|
# When field computation is done with a PX, the result is XHTML.
|
2013-07-08 16:39:16 -05:00
|
|
|
self.plainText = False
|
2014-12-08 07:52:04 -06:00
|
|
|
# Determine default value for "show"
|
|
|
|
if show == None:
|
|
|
|
# XHTML content in a Computed field generally corresponds to some
|
|
|
|
# custom XHTML widget. This is why, by default, we do not render it
|
|
|
|
# in the xml layout.
|
|
|
|
show = self.plainText and ('view', 'result', 'xml') or \
|
|
|
|
('view', 'result')
|
2013-09-20 10:42:07 -05:00
|
|
|
# If method is a PX, its context can be given in p_context.
|
2013-07-08 16:39:16 -05:00
|
|
|
self.context = context
|
|
|
|
Field.__init__(self, None, multiplicity, default, show, page, group,
|
|
|
|
layouts, move, indexed, searchable,
|
|
|
|
specificReadPermission, specificWritePermission, width,
|
|
|
|
height, None, colspan, master, masterValue, focus,
|
2014-03-05 09:19:11 -06:00
|
|
|
historized, mapping, label, sdefault, scolspan, swidth,
|
2014-12-09 08:19:28 -06:00
|
|
|
sheight, False, view, xml)
|
2013-07-08 16:39:16 -05:00
|
|
|
self.validable = False
|
|
|
|
|
|
|
|
def getValue(self, obj):
|
|
|
|
'''Computes the value instead of getting it in the database.'''
|
|
|
|
if not self.method: return
|
2013-09-20 10:42:07 -05:00
|
|
|
if isinstance(self.method, Px):
|
|
|
|
obj = obj.appy()
|
2013-09-23 15:36:09 -05:00
|
|
|
tool = obj.tool
|
2014-02-27 13:03:39 -06:00
|
|
|
req = obj.request
|
|
|
|
# Get the context of the currently executed PX if present
|
|
|
|
try:
|
|
|
|
ctx = req.pxContext
|
|
|
|
except AttributeError:
|
|
|
|
# Create some standard context
|
|
|
|
ctx = {'obj': obj, 'zobj': obj.o, 'field': self,
|
|
|
|
'req': req, 'tool': tool, 'ztool': tool.o,
|
|
|
|
'_': tool.translate, 'url': tool.o.getIncludeUrl}
|
2013-09-20 16:15:54 -05:00
|
|
|
if self.context: ctx.update(self.context)
|
2013-09-20 10:42:07 -05:00
|
|
|
return self.method(ctx)
|
2013-07-08 16:39:16 -05:00
|
|
|
else:
|
|
|
|
# self.method is a method that will return the field value
|
|
|
|
return self.callMethod(obj, self.method, cache=False)
|
|
|
|
|
2014-09-08 08:13:18 -05:00
|
|
|
def getFormattedValue(self, obj, value, showChanges=False, language=None):
|
2014-10-15 02:39:01 -05:00
|
|
|
if self.formatMethod:
|
|
|
|
res = self.formatMethod(obj, value)
|
|
|
|
else:
|
|
|
|
res = value
|
|
|
|
if not isinstance(res, basestring): res = str(res)
|
|
|
|
return res
|
2013-07-08 16:39:16 -05:00
|
|
|
# ------------------------------------------------------------------------------
|