appy.gen: ugly Zope acquisition-related bugfix; bugfix while rendering file widgets.
This commit is contained in:
parent
17f6d15185
commit
f1136eb786
|
@ -723,7 +723,7 @@ class Type:
|
||||||
|
|
||||||
def getValue(self, obj):
|
def getValue(self, obj):
|
||||||
'''Gets, on_obj, the value conforming to self's type definition.'''
|
'''Gets, on_obj, the value conforming to self's type definition.'''
|
||||||
value = getattr(obj, self.name, None)
|
value = getattr(obj.aq_base, self.name, None)
|
||||||
if (value == None):
|
if (value == None):
|
||||||
# If there is no value, get the default value if any
|
# If there is no value, get the default value if any
|
||||||
if not self.editDefault:
|
if not self.editDefault:
|
||||||
|
@ -1586,7 +1586,7 @@ class File(Type):
|
||||||
if isinstance(value, ZFileUpload):
|
if isinstance(value, ZFileUpload):
|
||||||
# The file content comes from a HTTP POST.
|
# The file content comes from a HTTP POST.
|
||||||
# Retrieve the existing value, or create one if None
|
# Retrieve the existing value, or create one if None
|
||||||
existingValue = getattr(obj, self.name, None)
|
existingValue = getattr(obj.aq_base, self.name, None)
|
||||||
if not existingValue:
|
if not existingValue:
|
||||||
existingValue = OFSImageFile(self.name, '', '')
|
existingValue = OFSImageFile(self.name, '', '')
|
||||||
# Set mimetype
|
# Set mimetype
|
||||||
|
@ -1722,7 +1722,7 @@ class Ref(Type):
|
||||||
if (layoutType == 'edit') and self.add: return False
|
if (layoutType == 'edit') and self.add: return False
|
||||||
if self.isBack:
|
if self.isBack:
|
||||||
if layoutType == 'edit': return False
|
if layoutType == 'edit': return False
|
||||||
else: return getattr(obj, self.name, None)
|
else: return getattr(obj.aq_base, self.name, None)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def getValue(self, obj, type='objects', noListIfSingleObj=False,
|
def getValue(self, obj, type='objects', noListIfSingleObj=False,
|
||||||
|
@ -1741,7 +1741,7 @@ class Ref(Type):
|
||||||
|
|
||||||
If p_someObjects is True, it returns an instance of SomeObjects
|
If p_someObjects is True, it returns an instance of SomeObjects
|
||||||
instead of returning a list of references.'''
|
instead of returning a list of references.'''
|
||||||
uids = getattr(obj, self.name, [])
|
uids = getattr(obj.aq_base, self.name, [])
|
||||||
if not uids:
|
if not uids:
|
||||||
# Maybe is there a default value?
|
# Maybe is there a default value?
|
||||||
defValue = Type.getValue(self, obj)
|
defValue = Type.getValue(self, obj)
|
||||||
|
@ -1818,7 +1818,7 @@ class Ref(Type):
|
||||||
return
|
return
|
||||||
# Gets the list of referred objects (=list of uids), or create it.
|
# Gets the list of referred objects (=list of uids), or create it.
|
||||||
obj = obj.o
|
obj = obj.o
|
||||||
refs = getattr(obj, self.name, None)
|
refs = getattr(obj.aq_base, self.name, None)
|
||||||
if refs == None:
|
if refs == None:
|
||||||
refs = obj.getProductConfig().PersistentList()
|
refs = obj.getProductConfig().PersistentList()
|
||||||
setattr(obj, self.name, refs)
|
setattr(obj, self.name, refs)
|
||||||
|
@ -1837,7 +1837,7 @@ class Ref(Type):
|
||||||
for v in value: self.unlinkObject(obj, v, back=back)
|
for v in value: self.unlinkObject(obj, v, back=back)
|
||||||
return
|
return
|
||||||
obj = obj.o
|
obj = obj.o
|
||||||
refs = getattr(obj, self.name, None)
|
refs = getattr(obj.aq_base, self.name, None)
|
||||||
if not refs: return
|
if not refs: return
|
||||||
# Unlink p_value
|
# Unlink p_value
|
||||||
uid = value.o.UID()
|
uid = value.o.UID()
|
||||||
|
@ -1869,7 +1869,7 @@ class Ref(Type):
|
||||||
objects[i] = objects[i].o
|
objects[i] = objects[i].o
|
||||||
uids = [o.UID() for o in objects]
|
uids = [o.UID() for o in objects]
|
||||||
# Unlink objects that are not referred anymore
|
# Unlink objects that are not referred anymore
|
||||||
refs = getattr(obj, self.name, None)
|
refs = getattr(obj.aq_base, self.name, None)
|
||||||
if refs:
|
if refs:
|
||||||
i = len(refs)-1
|
i = len(refs)-1
|
||||||
while i >= 0:
|
while i >= 0:
|
||||||
|
@ -2085,7 +2085,7 @@ class Pod(Type):
|
||||||
|
|
||||||
def isFrozen(self, obj):
|
def isFrozen(self, obj):
|
||||||
'''Is there a frozen document for p_self on p_obj?'''
|
'''Is there a frozen document for p_self on p_obj?'''
|
||||||
value = getattr(obj.o, self.name, None)
|
value = getattr(obj.o.aq_base, self.name, None)
|
||||||
return isinstance(value, obj.o.getProductConfig().File)
|
return isinstance(value, obj.o.getProductConfig().File)
|
||||||
|
|
||||||
def getToolInfo(self, obj):
|
def getToolInfo(self, obj):
|
||||||
|
@ -2098,7 +2098,7 @@ class Pod(Type):
|
||||||
# Get the output format(s)
|
# Get the output format(s)
|
||||||
if self.isFrozen(obj):
|
if self.isFrozen(obj):
|
||||||
# The only available format is the one from the frozen document
|
# The only available format is the one from the frozen document
|
||||||
fileName = getattr(obj.o, self.name).filename
|
fileName = getattr(obj.o.aq_base, self.name).filename
|
||||||
formats = (os.path.splitext(fileName)[1][1:],)
|
formats = (os.path.splitext(fileName)[1][1:],)
|
||||||
else:
|
else:
|
||||||
# Available formats are those which are selected in the tool.
|
# Available formats are those which are selected in the tool.
|
||||||
|
@ -2115,7 +2115,7 @@ class Pod(Type):
|
||||||
field has been frozen. Else, it means that the value must be
|
field has been frozen. Else, it means that the value must be
|
||||||
retrieved by calling pod to compute the result.'''
|
retrieved by calling pod to compute the result.'''
|
||||||
rq = getattr(obj, 'REQUEST', None)
|
rq = getattr(obj, 'REQUEST', None)
|
||||||
res = getattr(obj, self.name, None)
|
res = getattr(obj.aq_base, self.name, None)
|
||||||
if res and res.size: return FileWrapper(res) # Return the frozen file.
|
if res and res.size: return FileWrapper(res) # Return the frozen file.
|
||||||
# If we are here, it means that we must call pod to compute the file.
|
# If we are here, it means that we must call pod to compute the file.
|
||||||
# A Pod field differs from other field types because there can be
|
# A Pod field differs from other field types because there can be
|
||||||
|
|
|
@ -26,7 +26,8 @@ class BaseMixin:
|
||||||
return self
|
return self
|
||||||
o = property(get_o)
|
o = property(get_o)
|
||||||
|
|
||||||
def createOrUpdate(self, created, values):
|
def createOrUpdate(self, created, values,
|
||||||
|
initiator=None, initiatorField=None):
|
||||||
'''This method creates (if p_created is True) or updates an object.
|
'''This method creates (if p_created is True) or updates an object.
|
||||||
p_values are manipulated versions of those from the HTTP request.
|
p_values are manipulated versions of those from the HTTP request.
|
||||||
In the case of an object creation (p_created is True), p_self is a
|
In the case of an object creation (p_created is True), p_self is a
|
||||||
|
@ -56,13 +57,7 @@ class BaseMixin:
|
||||||
self.historizeData(previousData)
|
self.historizeData(previousData)
|
||||||
|
|
||||||
# Manage potential link with an initiator object
|
# Manage potential link with an initiator object
|
||||||
if created and rq.get('nav', None):
|
if created and initiator: initiator.appy().link(initiatorField, obj)
|
||||||
# Get the initiator
|
|
||||||
splitted = rq['nav'].split('.')
|
|
||||||
if splitted[0] == 'search': return # Not an initiator but a search.
|
|
||||||
initiator = self.getTool().getObject(splitted[1])
|
|
||||||
fieldName = splitted[2].split(':')[0]
|
|
||||||
initiator.appy().link(fieldName, obj)
|
|
||||||
|
|
||||||
# Manage "add" permissions and reindex the object
|
# Manage "add" permissions and reindex the object
|
||||||
obj._appy_managePermissions()
|
obj._appy_managePermissions()
|
||||||
|
@ -182,10 +177,11 @@ class BaseMixin:
|
||||||
# If this object is created from an initiator, get info about him.
|
# If this object is created from an initiator, get info about him.
|
||||||
initiator = None
|
initiator = None
|
||||||
initiatorPage = None
|
initiatorPage = None
|
||||||
|
initiatorField = None
|
||||||
if rq.get('nav', '').startswith('ref.'):
|
if rq.get('nav', '').startswith('ref.'):
|
||||||
splitted = rq['nav'].split('.')
|
splitted = rq['nav'].split('.')
|
||||||
initiator = tool.getObject(splitted[1])
|
initiator = tool.getObject(splitted[1])
|
||||||
initiatorPage = splitted[2].split(':')[1]
|
initiatorField, initiatorPage = splitted[2].split(':')
|
||||||
# If the user clicked on 'Cancel', go back to the previous page.
|
# If the user clicked on 'Cancel', go back to the previous page.
|
||||||
if rq.get('buttonCancel.x', None):
|
if rq.get('buttonCancel.x', None):
|
||||||
if initiator:
|
if initiator:
|
||||||
|
@ -230,14 +226,14 @@ class BaseMixin:
|
||||||
return self.gotoEdit()
|
return self.gotoEdit()
|
||||||
|
|
||||||
# Create or update the object in the database
|
# Create or update the object in the database
|
||||||
obj, msg = self.createOrUpdate(isNew, values)
|
obj, msg = self.createOrUpdate(isNew, values, initiator, initiatorField)
|
||||||
|
|
||||||
# Redirect the user to the appropriate page
|
# Redirect the user to the appropriate page
|
||||||
if not msg: msg = obj.translate('Changes saved.', domain='plone')
|
if not msg: msg = obj.translate('Changes saved.', domain='plone')
|
||||||
# If the object has already been deleted (ie, it is a kind of transient
|
# If the object has already been deleted (ie, it is a kind of transient
|
||||||
# object like a one-shot form and has already been deleted in method
|
# object like a one-shot form and has already been deleted in method
|
||||||
# onEdit), redirect to the main site page.
|
# onEdit), redirect to the main site page.
|
||||||
if not getattr(obj.getParentNode(), obj.id, None):
|
if not getattr(obj.getParentNode().aq_base, obj.id, None):
|
||||||
obj.unindexObject()
|
obj.unindexObject()
|
||||||
return self.goto(tool.getSiteUrl(), msg)
|
return self.goto(tool.getSiteUrl(), msg)
|
||||||
# If the user can't access the object anymore, redirect him to the
|
# If the user can't access the object anymore, redirect him to the
|
||||||
|
@ -426,6 +422,8 @@ class BaseMixin:
|
||||||
|
|
||||||
def getMethod(self, methodName):
|
def getMethod(self, methodName):
|
||||||
'''Returns the method named p_methodName.'''
|
'''Returns the method named p_methodName.'''
|
||||||
|
# If I write "self.aq_base" instead of self, acquisition will be
|
||||||
|
# broken on returned object.
|
||||||
return getattr(self, methodName, None)
|
return getattr(self, methodName, None)
|
||||||
|
|
||||||
def getFieldValue(self, name, onlyIfSync=False, layoutType=None):
|
def getFieldValue(self, name, onlyIfSync=False, layoutType=None):
|
||||||
|
@ -441,6 +439,11 @@ class BaseMixin:
|
||||||
field named p_name.'''
|
field named p_name.'''
|
||||||
return self.getAppyType(name).getFormattedValue(self, value)
|
return self.getAppyType(name).getFormattedValue(self, value)
|
||||||
|
|
||||||
|
def getFileInfo(self, fileObject):
|
||||||
|
'''Returns filename and size of p_fileObject.'''
|
||||||
|
if not fileObject: return {'filename': '', 'size': 0}
|
||||||
|
return {'filename': fileObject.filename, 'size': fileObject.size}
|
||||||
|
|
||||||
def getAppyRefs(self, name, startNumber=None):
|
def getAppyRefs(self, name, startNumber=None):
|
||||||
'''Gets the objects linked to me through Ref field named p_name.
|
'''Gets the objects linked to me through Ref field named p_name.
|
||||||
If p_startNumber is None, this method returns all referred objects.
|
If p_startNumber is None, this method returns all referred objects.
|
||||||
|
@ -498,7 +501,7 @@ class BaseMixin:
|
||||||
|
|
||||||
def getAppyRefIndex(self, fieldName, obj):
|
def getAppyRefIndex(self, fieldName, obj):
|
||||||
'''Gets the position of p_obj within Ref field named p_fieldName.'''
|
'''Gets the position of p_obj within Ref field named p_fieldName.'''
|
||||||
refs = getattr(self, fieldName, None)
|
refs = getattr(self.aq_base, fieldName, None)
|
||||||
if not refs: raise IndexError()
|
if not refs: raise IndexError()
|
||||||
return refs.index(obj.UID())
|
return refs.index(obj.UID())
|
||||||
|
|
||||||
|
@ -782,7 +785,7 @@ class BaseMixin:
|
||||||
'''This method changes the position of object with uid p_objectUid in
|
'''This method changes the position of object with uid p_objectUid in
|
||||||
reference field p_fieldName to p_newIndex i p_isDelta is False, or
|
reference field p_fieldName to p_newIndex i p_isDelta is False, or
|
||||||
to actualIndex+p_newIndex if p_isDelta is True.'''
|
to actualIndex+p_newIndex if p_isDelta is True.'''
|
||||||
refs = getattr(self, fieldName, None)
|
refs = getattr(self.aq_base, fieldName, None)
|
||||||
oldIndex = refs.index(objectUid)
|
oldIndex = refs.index(objectUid)
|
||||||
refs.remove(objectUid)
|
refs.remove(objectUid)
|
||||||
if isDelta:
|
if isDelta:
|
||||||
|
@ -1269,7 +1272,7 @@ class BaseMixin:
|
||||||
appyType = self.getAppyType(name)
|
appyType = self.getAppyType(name)
|
||||||
if (not appyType.type =='File') or not appyType.isShowable(self,'view'):
|
if (not appyType.type =='File') or not appyType.isShowable(self,'view'):
|
||||||
return
|
return
|
||||||
theFile = getattr(self, name, None)
|
theFile = getattr(self.aq_base, name, None)
|
||||||
if theFile:
|
if theFile:
|
||||||
response = self.REQUEST.RESPONSE
|
response = self.REQUEST.RESPONSE
|
||||||
response.setHeader('Content-Disposition', 'inline;filename="%s"' % \
|
response.setHeader('Content-Disposition', 'inline;filename="%s"' % \
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
<tal:comment replace="nothing">View macro for a File.</tal:comment>
|
<tal:comment replace="nothing">View macro for a File.</tal:comment>
|
||||||
<metal:view define-macro="view"
|
<metal:view define-macro="view"
|
||||||
tal:define="empty python: not value or not value.size;
|
tal:define="info python: contextObj.getFileInfo(value);
|
||||||
|
empty not: info/size;
|
||||||
imageSrc string:${contextObj/absolute_url}/download?name=$name">
|
imageSrc string:${contextObj/absolute_url}/download?name=$name">
|
||||||
<tal:file condition="python: not empty and not widget['isImage']">
|
<tal:file condition="python: not empty and not widget['isImage']">
|
||||||
<img tal:define="icon value/getBestIcon"
|
|
||||||
tal:condition="icon" tal:attributes="src string: $appUrl/$icon"/>
|
|
||||||
<a tal:attributes="href imageSrc"
|
<a tal:attributes="href imageSrc"
|
||||||
tal:content="value/filename">
|
tal:content="info/filename">
|
||||||
</a> -
|
</a> -
|
||||||
<i class="discreet" tal:content="python:'%sKb' % (value.size / 1024)"></i>
|
<i class="discreet" tal:content="python:'%sKb' % (info['size'] / 1024)"></i>
|
||||||
</tal:file>
|
</tal:file>
|
||||||
<tal:image condition="python: not empty and widget['isImage']">
|
<tal:image condition="python: not empty and widget['isImage']">
|
||||||
<img tal:attributes="src python: imageSrc" />
|
<img tal:attributes="src python: imageSrc" />
|
||||||
|
@ -17,14 +16,17 @@
|
||||||
</metal:view>
|
</metal:view>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Edit macro for an File.</tal:comment>
|
<tal:comment replace="nothing">Edit macro for an File.</tal:comment>
|
||||||
<metal:edit define-macro="edit">
|
<metal:edit define-macro="edit"
|
||||||
<tal:showFile condition="python: value and value.size">
|
tal:define="info python: contextObj.getFileInfo(value);
|
||||||
|
empty not: info/size;">
|
||||||
|
|
||||||
|
<tal:showFile condition="not: empty">
|
||||||
<metal:call use-macro="app/skyn/widgets/file/macros/view"/><br/>
|
<metal:call use-macro="app/skyn/widgets/file/macros/view"/><br/>
|
||||||
</tal:showFile>
|
</tal:showFile>
|
||||||
<tal:editButtons condition="python: value and value.size">
|
<tal:editButtons condition="not: empty">
|
||||||
<tal:comment replace="nothing">Keep the file untouched.</tal:comment>
|
<tal:comment replace="nothing">Keep the file untouched.</tal:comment>
|
||||||
<input type="radio" value="nochange"
|
<input type="radio" value="nochange"
|
||||||
tal:attributes="checked python:test(value.size!=0, 'checked', None);
|
tal:attributes="checked python:test(info['size']!=0, 'checked', None);
|
||||||
name string:${name}_delete;
|
name string:${name}_delete;
|
||||||
id string:${name}_nochange;
|
id string:${name}_nochange;
|
||||||
onclick string:document.getElementById('${name}_file').disabled=true;"/>
|
onclick string:document.getElementById('${name}_file').disabled=true;"/>
|
||||||
|
@ -43,23 +45,23 @@
|
||||||
</tal:delete>
|
</tal:delete>
|
||||||
<tal:comment replace="nothing">Replace with a new file.</tal:comment>
|
<tal:comment replace="nothing">Replace with a new file.</tal:comment>
|
||||||
<input type="radio" value=""
|
<input type="radio" value=""
|
||||||
tal:attributes="checked python:test(value.size==0, 'checked', None);
|
tal:attributes="checked python:test(info['size']==0, 'checked', None);
|
||||||
name string:${name}_delete;
|
name string:${name}_delete;
|
||||||
id string:${name}_upload;
|
id string:${name}_upload;
|
||||||
onclick string:document.getElementById('${name}_file').disabled=false"/>
|
onclick string:document.getElementById('${name}_file').disabled=false"/>
|
||||||
<label tal:attributes="for string:${name}_upload;"
|
<label tal:attributes="for string:${name}_upload;"
|
||||||
i18n:translate="upload_file" i18n:domain="plone">Replace it with a new file</label>
|
i18n:translate="upload_file" i18n:domain="plone">Replace it with a new file</label>
|
||||||
<br/>
|
<br/>
|
||||||
</tal:editButtons>
|
</tal:editButtons>
|
||||||
<tal:comment replace="nothing">The upload field.</tal:comment>
|
<tal:comment replace="nothing">The upload field.</tal:comment>
|
||||||
<input type="file"
|
<input type="file"
|
||||||
tal:attributes="name string:${name}_file;
|
tal:attributes="name string:${name}_file;
|
||||||
id string:${name}_file;
|
id string:${name}_file;
|
||||||
size widget/width"/>
|
size widget/width"/>
|
||||||
<script type="text/javascript"
|
<script type="text/javascript"
|
||||||
tal:define="isDisabled python:test(value and value.size, 'true', 'false')"
|
tal:define="isDisabled python:test(empty, 'false', 'true')"
|
||||||
tal:content="string: document.getElementById('${name}_file').disabled=$isDisabled;">
|
tal:content="string: document.getElementById('${name}_file').disabled=$isDisabled;">
|
||||||
</script>
|
</script>
|
||||||
</metal:edit>
|
</metal:edit>
|
||||||
|
|
||||||
<tal:comment replace="nothing">Cell macro for an File.</tal:comment>
|
<tal:comment replace="nothing">Cell macro for an File.</tal:comment>
|
||||||
|
|
Loading…
Reference in a new issue