appy.gen: Type 'float': added the possibility to define a separator for thousands; bugfixes in master/slave relationships; permission-related bugfix while creating objects through AbstractWrapper.create; appy.shared.diff: more improvements (still ongoing work).
This commit is contained in:
parent
040cdafb8c
commit
8e1760842e
12 changed files with 139 additions and 55 deletions
|
@ -25,7 +25,7 @@ labelTypes = ('label', 'descr', 'help')
|
|||
|
||||
def initMasterValue(v):
|
||||
'''Standardizes p_v as a list of strings.'''
|
||||
if not v: res = []
|
||||
if not isinstance(v, bool) and not v: res = []
|
||||
elif type(v) not in sequenceTypes: res = [v]
|
||||
else: res = v
|
||||
return [str(v) for v in res]
|
||||
|
@ -959,6 +959,7 @@ class Integer(Type):
|
|||
|
||||
class Float(Type):
|
||||
allowedDecimalSeps = (',', '.')
|
||||
allowedThousandsSeps = (' ', '')
|
||||
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
||||
default=None, optional=False, editDefault=False, show=True,
|
||||
page='main', group=None, layouts=None, move=0, indexed=False,
|
||||
|
@ -966,7 +967,7 @@ class Float(Type):
|
|||
specificWritePermission=False, width=6, height=None,
|
||||
maxChars=13, colspan=1, master=None, masterValue=None,
|
||||
focus=False, historized=False, mapping=None, label=None,
|
||||
precision=None, sep=(',', '.')):
|
||||
precision=None, sep=(',', '.'), tsep=' '):
|
||||
# The precision is the number of decimal digits. This number is used
|
||||
# for rendering the float, but the internal float representation is not
|
||||
# rounded.
|
||||
|
@ -981,6 +982,7 @@ class Float(Type):
|
|||
for sep in self.sep:
|
||||
if sep not in Float.allowedDecimalSeps:
|
||||
raise 'Char "%s" is not allowed as decimal separator.' % sep
|
||||
self.tsep = tsep
|
||||
Type.__init__(self, validator, multiplicity, index, default, optional,
|
||||
editDefault, show, page, group, layouts, move, indexed,
|
||||
False, specificReadPermission, specificWritePermission,
|
||||
|
@ -989,11 +991,13 @@ class Float(Type):
|
|||
self.pythonType = float
|
||||
|
||||
def getFormattedValue(self, obj, value):
|
||||
return formatNumber(value, sep=self.sep[0], precision=self.precision)
|
||||
return formatNumber(value, sep=self.sep[0], precision=self.precision,
|
||||
tsep=self.tsep)
|
||||
|
||||
def validateValue(self, obj, value):
|
||||
# Replace used separator with the Python separator '.'
|
||||
for sep in self.sep: value = value.replace(sep, '.')
|
||||
value = value.replace(self.tsep, '')
|
||||
try:
|
||||
value = self.pythonType(value)
|
||||
except ValueError:
|
||||
|
@ -1002,6 +1006,7 @@ class Float(Type):
|
|||
def getStorableValue(self, value):
|
||||
if not self.isEmptyValue(value):
|
||||
for sep in self.sep: value = value.replace(sep, '.')
|
||||
value = value.replace(self.tsep, '')
|
||||
return self.pythonType(value)
|
||||
|
||||
class String(Type):
|
||||
|
@ -1752,7 +1757,7 @@ class Ref(Type):
|
|||
if type == 'uids':
|
||||
ref = uids[i]
|
||||
else:
|
||||
ref = obj.portal_catalog(UID=uids[i])[0].getObject()
|
||||
ref = obj.uid_catalog(UID=uids[i])[0].getObject()
|
||||
if type == 'objects':
|
||||
ref = ref.appy()
|
||||
res.objects.append(ref)
|
||||
|
|
|
@ -452,7 +452,6 @@ class ZopeInstaller:
|
|||
self.config.listTypes(self.productName)
|
||||
contentTypes, constructors, ftis = self.config.process_types(
|
||||
self.config.listTypes(self.productName), self.productName)
|
||||
|
||||
self.config.cmfutils.ContentInit(self.productName + ' Content',
|
||||
content_types = contentTypes,
|
||||
permission = self.defaultAddContentPermission,
|
||||
|
|
|
@ -217,8 +217,8 @@ function getSlaveInfo(slave, infoType) {
|
|||
|
||||
function getMasterValues(master) {
|
||||
// Returns the list of values that p_master currently has.
|
||||
if (master.tagName == 'SPAN') {
|
||||
res = master.attributes['value'].value;
|
||||
if ((master.tagName == 'INPUT') && (master.type != 'checkbox')) {
|
||||
res = master.value;
|
||||
if ((res[0] == '(') || (res[0] == '[')) {
|
||||
// There are multiple values, split it
|
||||
values = res.substring(1, res.length-1).split(',');
|
||||
|
@ -247,17 +247,17 @@ function getMasterValues(master) {
|
|||
function getSlaves(master) {
|
||||
// Gets all the slaves of master.
|
||||
allSlaves = document.getElementsByName('slave');
|
||||
res = [];
|
||||
res = [];
|
||||
masterName = master.attributes['name'].value;
|
||||
if (master.type == 'checkbox') {
|
||||
masterName = masterName.substr(0, masterName.length-8);
|
||||
}
|
||||
slavePrefix = 'slave_' + masterName + '_';
|
||||
for (var i=0; i < slaves.length; i++){
|
||||
cssClasses = slaves[i].className.split(' ');
|
||||
for (var i=0; i < allSlaves.length; i++){
|
||||
cssClasses = allSlaves[i].className.split(' ');
|
||||
for (var j=0; j < cssClasses.length; j++) {
|
||||
if (cssClasses[j].indexOf(slavePrefix) == 0) {
|
||||
res.push(slaves[i]);
|
||||
res.push(allSlaves[i]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -265,9 +265,13 @@ function getSlaves(master) {
|
|||
return res;
|
||||
}
|
||||
|
||||
function updateSlaves(master) {
|
||||
function updateSlaves(master, slave) {
|
||||
// Given the value(s) in a master field, we must update slave's visibility.
|
||||
slaves = getSlaves(master);
|
||||
// If p_slave is given, it updates only this slave. Else, it updates all
|
||||
// slaves of p_master.
|
||||
var slaves = null;
|
||||
if (slave) { slaves = [slave]; }
|
||||
else { slaves = getSlaves(master); }
|
||||
masterValues = getMasterValues(master);
|
||||
for (var i=0; i < slaves.length; i++) {
|
||||
showSlave = false;
|
||||
|
@ -286,13 +290,12 @@ function initSlaves() {
|
|||
// When the current page is loaded, we must set the correct state for all
|
||||
// slave fields.
|
||||
slaves = document.getElementsByName('slave');
|
||||
walkedMasters = {}; // Remember the already walked masters.
|
||||
for (var i=0; i < slaves.length; i++) {
|
||||
i = slaves.length -1;
|
||||
while (i >= 0) {
|
||||
masterName = getSlaveInfo(slaves[i], 'masterName');
|
||||
if (masterName in walkedMasters) continue;
|
||||
master = document.getElementById(masterName);
|
||||
updateSlaves(master);
|
||||
walkedMasters[masterName] = 'walked';
|
||||
updateSlaves(master, slaves[i]);
|
||||
i -= 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<tal:comment replace="nothing">View macro for a Boolean.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:attributes="class masterCss; value rawValue; name name; id name"
|
||||
tal:content="value"></span>
|
||||
<span tal:replace="value"></span>
|
||||
<input type="hidden" tal:condition="masterCss"
|
||||
tal:attributes="class masterCss; value rawValue; name name; id name"/>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Boolean.</tal:comment>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<tal:comment replace="nothing">View macro for a Float.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:content="value"
|
||||
tal:attributes="value value; class masterCss; name name; id name"></span>
|
||||
<span tal:replace="value"></span>
|
||||
<input type="hidden" tal:condition="masterCss"
|
||||
tal:attributes="class masterCss; value value; name name; id name"/>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Float.</tal:comment>
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
<tal:comment replace="nothing">View macro for an Integer.</tal:comment>
|
||||
<metal:view define-macro="view">
|
||||
<span tal:content="value"
|
||||
tal:attributes="value value; class masterCss; name name; id name"></span>
|
||||
<span tal:replace="value"></span>
|
||||
<input type="hidden" tal:condition="masterCss"
|
||||
tal:attributes="class masterCss; value value; name name; id name"/>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for an Integer.</tal:comment>
|
||||
|
|
|
@ -130,7 +130,6 @@
|
|||
The definition of "atMostOneRef" above may sound strange: we shouldn't check the actual number
|
||||
of referenced objects. But for back references people often forget to specify multiplicities.
|
||||
So concretely, multiplicities (0,None) are coded as (0,1).</tal:comment>
|
||||
|
||||
<tal:atMostOneReference condition="atMostOneRef">
|
||||
<tal:comment replace="nothing">Display a simplified widget if maximum number of
|
||||
referenced objects is 1.</tal:comment>
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
<tal:comment replace="nothing">View macro for a String.</tal:comment>
|
||||
<metal:view define-macro="view"
|
||||
tal:define="fmt widget/format">
|
||||
<span tal:condition="python: fmt in (0, 3)"
|
||||
tal:attributes="class masterCss; value rawValue; name name; id name">
|
||||
<span tal:condition="python: fmt in (0, 3)">
|
||||
<ul tal:condition="python: value and isMultiple">
|
||||
<li tal:repeat="sv value"><i tal:content="structure sv"></i></li>
|
||||
</ul>
|
||||
|
@ -16,6 +15,8 @@
|
|||
tal:replace="structure python: contextObj.formatText(value, format='html')"/>
|
||||
<span tal:condition="python: value and (fmt == 2)" tal:replace="structure value"/>
|
||||
</tal:formattedString>
|
||||
<input type="hidden" tal:condition="masterCss"
|
||||
tal:attributes="class masterCss; value rawValue; name name; id name"/>
|
||||
</metal:view>
|
||||
|
||||
<tal:comment replace="nothing">Edit macro for a String.</tal:comment>
|
||||
|
|
|
@ -148,6 +148,14 @@ class AbstractWrapper(object):
|
|||
else:
|
||||
folder = self.o.getParentNode()
|
||||
# Create the object
|
||||
# -------------------- Try to replace invokeFactory --------------------
|
||||
#folder._objects = folder._objects + ({'id':id,'meta_type':portalType},)
|
||||
#folder._setOb(id, ob)
|
||||
#ploneObj = self._getOb(id)
|
||||
#ob._setPortalTypeName(self.getId())
|
||||
#ob.notifyWorkflowCreated()
|
||||
# + Check what's done in Archetypes/ClassGen.py in m_genCtor
|
||||
# ------------------------------ Try end -------------------------------
|
||||
folder.invokeFactory(portalType, objId)
|
||||
ploneObj = getattr(folder, objId)
|
||||
appyObj = ploneObj.appy()
|
||||
|
@ -157,6 +165,7 @@ class AbstractWrapper(object):
|
|||
if isField:
|
||||
# Link the object to this one
|
||||
appyType.linkObject(self.o, ploneObj)
|
||||
ploneObj._appy_managePermissions()
|
||||
# Call custom initialization
|
||||
if externalData: param = externalData
|
||||
else: param = True
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue