[gen] Master-slave fields: slave values can now ajax-change when the user modifies master values.

This commit is contained in:
Gaetan Delannay 2014-03-03 18:54:21 +01:00
parent f7172be6ee
commit b8ceb66a49
15 changed files with 253 additions and 74 deletions

View file

@ -253,6 +253,17 @@ def keepDigits(s):
if c.isdigit(): res += c
return res
def getStringDict(d):
'''Gets the string literal corresponding to dict p_d.'''
res = []
for k, v in d.iteritems():
if type(v) not in sequenceTypes:
value = "'%s':'%s'" % (k, v)
else:
value = "'%s':%s" % (k, v)
res.append(value)
return '{%s}' % ','.join(res)
# ------------------------------------------------------------------------------
def formatNumber(n, sep=',', precision=2, tsep=' '):
'''Returns a string representation of number p_n, which can be a float

View file

@ -596,31 +596,48 @@ class XmlMarshaller:
def dumpFile(self, res, v):
'''Dumps a file into the result.'''
if not v: return
w = res.write
# p_value contains the (possibly binary) content of a file. We will
# encode it in Base64, in one or several parts.
partTag = self.getTagName('part')
res.write('<%s type="base64" number="1">' % partTag)
if hasattr(v, 'data'):
# The file is an Archetypes file.
valueType = v.data.__class__.__name__
if valueType == 'Pdata':
if v.data.__class__.__name__ == 'Pdata':
# There will be several parts.
res.write(v.data.data.encode('base64'))
w(v.data.data.encode('base64'))
# Write subsequent parts
nextPart = v.data.next
nextPartNumber = 2
nextPartNb = 2
while nextPart:
res.write('</%s>' % partTag) # Close the previous part
res.write('<%s type="base64" number="%d">' % \
(partTag, nextPartNumber))
res.write(nextPart.data.encode('base64'))
w('</%s>' % partTag) # Close the previous part
w('<%s type="base64" number="%d">' % (partTag, nextPartNb))
w(nextPart.data.encode('base64'))
nextPart = nextPart.next
nextPartNumber += 1
nextPartNb += 1
else:
res.write(v.data.encode('base64'))
w(v.data.encode('base64'))
w('</%s>' % partTag)
elif hasattr(v, 'uploadName'):
# The file is a Appy FileInfo instance. Read the file from disk.
filePath = v.getFilePath(self.instance)
f = file(filePath, 'rb')
partNb = 1
while True:
chunk = f.read(v.BYTES)
if not chunk: break
# We have one more chunk. Dump the start tag (excepted if it is
# the first chunk: the start tag has already been dumped, see
# above).
if partNb > 1:
w('<%s type="base64" number="%d">' % (partTag, partNb))
w(chunk.encode('base64'))
w('</%s>' % partTag) # Close the tag
partNb += 1
f.close()
else:
res.write(v.encode('base64'))
res.write('</%s>' % partTag)
w(v.encode('base64'))
w('</%s>' % partTag)
def dumpDict(self, res, v):
'''Dumps the XML version of dict p_v.'''
@ -704,11 +721,22 @@ class XmlMarshaller:
if fieldValue: length = len(fieldValue)
res.write(' count="%d"' % length)
if fType == 'file':
# Get the MIME type
mimeType = None
if hasattr(fieldValue, 'content_type'):
res.write(' mimeType="%s"' % fieldValue.content_type)
mimeType = fieldValue.content_type
elif hasattr(fieldValue, 'mimeType'):
mimeType = fieldValue.mimeType
if mimeType: res.write(' mimeType="%s"' % mimeType)
# Get the file name
fileName = None
if hasattr(fieldValue, 'filename'):
fileName = fieldValue.filename
elif hasattr(fieldValue, 'uploadName'):
fileName = fieldValue.uploadName
if fileName:
res.write(' name="')
self.dumpString(res, fieldValue.filename)
self.dumpString(res, fileName)
res.write('"')
res.write('>')
# Dump the field value
@ -724,6 +752,8 @@ class XmlMarshaller:
an instance at all, but another Python data structure or basic type,
p_objectType is ignored.'''
self.objectType = objectType
# The Appy object is needed to marshall its File fields.
if objectType == 'appy': self.instance = instance
# Call the XmlMarshaller constructor if it hasn't been called yet.
if not hasattr(self, 'cdata'):
XmlMarshaller.__init__(self)
@ -789,7 +819,6 @@ class XmlMarshaller:
if field.type == 'File':
fieldType = 'file'
v = field.getValue(instance)
if v: v = v._zopeFile
elif field.type == 'Ref':
fieldType = 'ref'
v = field.getValue(instance, type='zobjects')