Bugfixes in master/slave relationships for groups; small bugfix in the way to express layouts; bugfixes while generating optional fields in the tool; obj.link can now links several objects at once; bugfix in page navigation.
This commit is contained in:
parent
50c8a139fc
commit
30768655f6
|
@ -137,8 +137,8 @@ class Group:
|
||||||
self.css_class = css_class
|
self.css_class = css_class
|
||||||
self.master = None
|
self.master = None
|
||||||
self.masterValue = None
|
self.masterValue = None
|
||||||
if self.master:
|
if master:
|
||||||
self._addMaster(self, master, masterValue)
|
self._addMaster(master, masterValue)
|
||||||
|
|
||||||
def _addMaster(self, master, masterValue):
|
def _addMaster(self, master, masterValue):
|
||||||
'''Specifies this group being a slave of another field: we will add css
|
'''Specifies this group being a slave of another field: we will add css
|
||||||
|
@ -545,9 +545,12 @@ class Type:
|
||||||
# Get the global default layouts
|
# Get the global default layouts
|
||||||
layouts = copy.deepcopy(defaultFieldLayouts)
|
layouts = copy.deepcopy(defaultFieldLayouts)
|
||||||
else:
|
else:
|
||||||
if isinstance(layouts, basestring) or isinstance(layouts, Table):
|
if isinstance(layouts, basestring):
|
||||||
# The user specified a single layoutString (the "edit" one)
|
# The user specified a single layoutString (the "edit" one)
|
||||||
layouts = {'edit': layouts}
|
layouts = {'edit': layouts}
|
||||||
|
elif isinstance(layouts, Table):
|
||||||
|
# Idem, but with a Table instance
|
||||||
|
layouts = {'edit': Table(other=layouts)}
|
||||||
else:
|
else:
|
||||||
layouts = copy.deepcopy(layouts)
|
layouts = copy.deepcopy(layouts)
|
||||||
# Here, we make a copy of the layouts, because every layout can
|
# Here, we make a copy of the layouts, because every layout can
|
||||||
|
@ -1260,7 +1263,7 @@ class Ref(Type):
|
||||||
group=None, layouts=None, showHeaders=False, shownInfo=(),
|
group=None, layouts=None, showHeaders=False, shownInfo=(),
|
||||||
select=None, maxPerPage=30, move=0, indexed=False,
|
select=None, maxPerPage=30, move=0, indexed=False,
|
||||||
searchable=False, specificReadPermission=False,
|
searchable=False, specificReadPermission=False,
|
||||||
specificWritePermission=False, width=None, height=None,
|
specificWritePermission=False, width=None, height=5,
|
||||||
colspan=1, master=None, masterValue=None, focus=False,
|
colspan=1, master=None, masterValue=None, focus=False,
|
||||||
historized=False):
|
historized=False):
|
||||||
self.klass = klass
|
self.klass = klass
|
||||||
|
|
|
@ -136,7 +136,7 @@ class Table(LayoutElement):
|
||||||
self.layoutString = Table.deriveLayout(other.layoutString,
|
self.layoutString = Table.deriveLayout(other.layoutString,
|
||||||
derivedType)
|
derivedType)
|
||||||
else:
|
else:
|
||||||
self.layoutString = layoutString
|
self.layoutString = other.layoutString
|
||||||
source = 'other.'
|
source = 'other.'
|
||||||
else:
|
else:
|
||||||
source = ''
|
source = ''
|
||||||
|
|
|
@ -17,6 +17,14 @@ class BaseMixin:
|
||||||
a subclass of it.'''
|
a subclass of it.'''
|
||||||
_appy_meta_type = 'Class'
|
_appy_meta_type = 'Class'
|
||||||
|
|
||||||
|
def get_o(self):
|
||||||
|
'''In some cases, we wand the Zope object, we don't know if the current
|
||||||
|
object is a Zope or Appy object. By defining this property,
|
||||||
|
"someObject.o" produces always the Zope object, be someObject an Appy
|
||||||
|
or Zope object.'''
|
||||||
|
return self
|
||||||
|
o = property(get_o)
|
||||||
|
|
||||||
def createOrUpdate(self, created, values):
|
def createOrUpdate(self, created, values):
|
||||||
'''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.
|
||||||
|
@ -283,8 +291,7 @@ class BaseMixin:
|
||||||
((prev == '') and (curr == None)):
|
((prev == '') and (curr == None)):
|
||||||
del previousData[field]
|
del previousData[field]
|
||||||
if (appyType.type == 'Ref') and (field in previousData):
|
if (appyType.type == 'Ref') and (field in previousData):
|
||||||
titles = [r.title for r in previousData[field]]
|
previousData[field] = [r.title for r in previousData[field]]
|
||||||
previousData[field] = ','.join(titles)
|
|
||||||
if previousData:
|
if previousData:
|
||||||
self.addDataChange(previousData)
|
self.addDataChange(previousData)
|
||||||
|
|
||||||
|
@ -510,10 +517,15 @@ class BaseMixin:
|
||||||
return phaseInfo
|
return phaseInfo
|
||||||
# If I am here, it means that the page as defined in the request,
|
# If I am here, it means that the page as defined in the request,
|
||||||
# or 'main' by default, is not existing nor visible in any phase.
|
# or 'main' by default, is not existing nor visible in any phase.
|
||||||
# In this case I set the page as being the first visible page in
|
# In this case I find the first visible page among all phases.
|
||||||
# the first visible phase.
|
viewAttr = 'showOn%s' % layoutType.capitalize()
|
||||||
rq.set('page', res[0]['pages'][0])
|
for phase in res:
|
||||||
return res[0]
|
for page in phase['pages']:
|
||||||
|
if phase['pagesInfo'][page][viewAttr]:
|
||||||
|
rq.set('page', page)
|
||||||
|
pageFound = True
|
||||||
|
break
|
||||||
|
return phase
|
||||||
else:
|
else:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
|
|
@ -149,7 +149,7 @@ class Tool(ModelClass):
|
||||||
res.optional = False
|
res.optional = False
|
||||||
res.show = True
|
res.show = True
|
||||||
res.group = copy.copy(appyType.group)
|
res.group = copy.copy(appyType.group)
|
||||||
res.phase = 'main'
|
res.page = copy.copy(appyType.page)
|
||||||
# Set default layouts for all Tool fields
|
# Set default layouts for all Tool fields
|
||||||
res.layouts = res.formatLayouts(None)
|
res.layouts = res.formatLayouts(None)
|
||||||
res.specificReadPermission = False
|
res.specificReadPermission = False
|
||||||
|
@ -177,7 +177,7 @@ class Tool(ModelClass):
|
||||||
fieldType.validator = []
|
fieldType.validator = []
|
||||||
klass._appy_addField(fieldName, fieldType, fieldDescr.classDescr)
|
klass._appy_addField(fieldName, fieldType, fieldDescr.classDescr)
|
||||||
fieldType.validator.append(fieldDescr.fieldName)
|
fieldType.validator.append(fieldDescr.fieldName)
|
||||||
fieldType.page = 'data'
|
fieldType.page.name = 'data'
|
||||||
fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
|
fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -186,7 +186,7 @@ class Tool(ModelClass):
|
||||||
fieldName = 'defaultValueFor%s_%s' % (className, fieldDescr.fieldName)
|
fieldName = 'defaultValueFor%s_%s' % (className, fieldDescr.fieldName)
|
||||||
fieldType = klass._appy_copyField(fieldDescr.appyType)
|
fieldType = klass._appy_copyField(fieldDescr.appyType)
|
||||||
klass._appy_addField(fieldName, fieldType, fieldDescr.classDescr)
|
klass._appy_addField(fieldName, fieldType, fieldDescr.classDescr)
|
||||||
fieldType.page = 'data'
|
fieldType.page.name = 'data'
|
||||||
fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
|
fieldType.group = Group(fieldDescr.classDescr.klass.__name__)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
|
|
@ -258,7 +258,7 @@
|
||||||
refUids python: [o.UID() for o in contextObj.getAppyRefs(name)['objects']];
|
refUids python: [o.UID() for o in contextObj.getAppyRefs(name)['objects']];
|
||||||
isBeingCreated python: contextObj.isTemporary() or ('/portal_factory/' in contextObj.absolute_url())">
|
isBeingCreated python: contextObj.isTemporary() or ('/portal_factory/' in contextObj.absolute_url())">
|
||||||
|
|
||||||
<select tal:attributes="name rname;
|
<select tal:attributes="name rname; size widget/height;
|
||||||
multiple python: isMultiple and 'multiple' or ''">
|
multiple python: isMultiple and 'multiple' or ''">
|
||||||
<option tal:condition="not: isMultiple" i18n:translate="choose_a_value"></option>
|
<option tal:condition="not: isMultiple" i18n:translate="choose_a_value"></option>
|
||||||
<tal:ref repeat="refObj allObjects">
|
<tal:ref repeat="refObj allObjects">
|
||||||
|
|
|
@ -112,20 +112,26 @@ class AbstractWrapper:
|
||||||
|
|
||||||
def link(self, fieldName, obj):
|
def link(self, fieldName, obj):
|
||||||
'''This method links p_obj to this one through reference field
|
'''This method links p_obj to this one through reference field
|
||||||
p_fieldName.'''
|
p_fieldName. p_obj can also be a list or tuple of objects.'''
|
||||||
if isinstance(obj, AbstractWrapper):
|
|
||||||
obj = obj.o
|
|
||||||
postfix = 'et%s%s' % (fieldName[0].upper(), fieldName[1:])
|
postfix = 'et%s%s' % (fieldName[0].upper(), fieldName[1:])
|
||||||
# Update the Archetypes reference field
|
# Update the Archetypes reference field
|
||||||
exec 'objs = self.o.g%s()' % postfix
|
exec 'objs = self.o.g%s()' % postfix
|
||||||
if not objs:
|
if not objs:
|
||||||
objs = []
|
objs = []
|
||||||
elif type(objs) not in (list, tuple):
|
elif type(objs) not in sequenceTypes:
|
||||||
objs = [objs]
|
objs = [objs]
|
||||||
objs.append(obj)
|
# Add p_obj to the existing objects
|
||||||
|
if type(obj) in sequenceTypes:
|
||||||
|
for o in obj: objs.append(o.o)
|
||||||
|
else:
|
||||||
|
objs.append(obj.o)
|
||||||
exec 'self.o.s%s(objs)' % postfix
|
exec 'self.o.s%s(objs)' % postfix
|
||||||
# Update the ordered list of references
|
# Update the ordered list of references
|
||||||
self.o._appy_getSortedField(fieldName).append(obj.UID())
|
sorted = self.o._appy_getSortedField(fieldName)
|
||||||
|
if type(obj) in sequenceTypes:
|
||||||
|
for o in obj: sorted.append(o.o.UID())
|
||||||
|
else:
|
||||||
|
sorted.append(obj.o.UID())
|
||||||
|
|
||||||
def sort(self, fieldName, sortKey='title', reverse=False):
|
def sort(self, fieldName, sortKey='title', reverse=False):
|
||||||
'''Sorts referred elements linked to p_self via p_fieldName according
|
'''Sorts referred elements linked to p_self via p_fieldName according
|
||||||
|
|
|
@ -83,13 +83,15 @@ class PhaseDescr(Descr):
|
||||||
if (appyType.page.name in self.pages) or \
|
if (appyType.page.name in self.pages) or \
|
||||||
(appyType.page.name in self.hiddenPages): return
|
(appyType.page.name in self.hiddenPages): return
|
||||||
# Add the page only if it must be shown.
|
# Add the page only if it must be shown.
|
||||||
if appyType.page.isShowable(obj, layoutType):
|
isShowableOnView = appyType.page.isShowable(obj, 'view')
|
||||||
|
isShowableOnEdit = appyType.page.isShowable(obj, 'edit')
|
||||||
|
if isShowableOnView or isShowableOnEdit:
|
||||||
# The page must be added.
|
# The page must be added.
|
||||||
self.pages.append(appyType.page.name)
|
self.pages.append(appyType.page.name)
|
||||||
# Create the dict about page information and add it in self.pageInfo
|
# Create the dict about page information and add it in self.pageInfo
|
||||||
pageInfo = {'page': appyType.page,
|
pageInfo = {'page': appyType.page,
|
||||||
'showOnView': appyType.page.isShowable(obj, 'view'),
|
'showOnView': isShowableOnView,
|
||||||
'showOnEdit': appyType.page.isShowable(obj, 'edit')}
|
'showOnEdit': isShowableOnEdit}
|
||||||
pageInfo.update(appyType.page.getInfo(obj, layoutType))
|
pageInfo.update(appyType.page.getInfo(obj, layoutType))
|
||||||
self.pagesInfo[appyType.page.name] = pageInfo
|
self.pagesInfo[appyType.page.name] = pageInfo
|
||||||
else:
|
else:
|
||||||
|
|
Loading…
Reference in a new issue