[gen] Added some layouts for Ref fields in Ref.wLayouts and Ref.wdLayouts; added a new, simpler way of defining auto-references (=Ref fields that refer to the class containing the field), via method appy.gen.autoref; stop catching exceptions raised by Actions (so a partial action can't be committed anymore).
This commit is contained in:
parent
61b0ed2fce
commit
812bda7452
|
@ -1729,6 +1729,12 @@ class File(Type):
|
||||||
else: setattr(obj, self.name, None)
|
else: setattr(obj, self.name, None)
|
||||||
|
|
||||||
class Ref(Type):
|
class Ref(Type):
|
||||||
|
# Some default layouts. "w" stands for "wide": those layouts produce tables
|
||||||
|
# of Ref objects whose width is 100%.
|
||||||
|
wLayouts = Table('lrv-f', width='100%')
|
||||||
|
# "d" stands for "description": a description label is added.
|
||||||
|
wdLayouts = {'view': Table('l-d-f', width='100%')}
|
||||||
|
|
||||||
def __init__(self, klass=None, attribute=None, validator=None,
|
def __init__(self, klass=None, attribute=None, validator=None,
|
||||||
multiplicity=(0,1), index=None, default=None, optional=False,
|
multiplicity=(0,1), index=None, default=None, optional=False,
|
||||||
editDefault=False, add=False, addConfirm=False, noForm=False,
|
editDefault=False, add=False, addConfirm=False, noForm=False,
|
||||||
|
@ -2037,6 +2043,26 @@ class Ref(Type):
|
||||||
raise Unauthorized("User can't write Ref field '%s' (%s)." % \
|
raise Unauthorized("User can't write Ref field '%s' (%s)." % \
|
||||||
(self.name, may.msg))
|
(self.name, may.msg))
|
||||||
|
|
||||||
|
def autoref(klass, field):
|
||||||
|
'''klass.field is a Ref to p_klass. This kind of auto-reference can't be
|
||||||
|
declared in the "normal" way, like this:
|
||||||
|
|
||||||
|
class A:
|
||||||
|
attr1 = Ref(A)
|
||||||
|
|
||||||
|
because at the time Python encounters the static declaration
|
||||||
|
"attr1 = Ref(A)", class A is not completely defined yet.
|
||||||
|
|
||||||
|
This method allows to overcome this problem. You can write such
|
||||||
|
auto-reference like this:
|
||||||
|
|
||||||
|
class A:
|
||||||
|
attr1 = Ref(None)
|
||||||
|
autoref(A, A.attr1)
|
||||||
|
'''
|
||||||
|
field.klass = klass
|
||||||
|
setattr(klass, field.back.attribute, field.back)
|
||||||
|
|
||||||
class Computed(Type):
|
class Computed(Type):
|
||||||
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
def __init__(self, validator=None, multiplicity=(0,1), index=None,
|
||||||
default=None, optional=False, editDefault=False, show='view',
|
default=None, optional=False, editDefault=False, show='view',
|
||||||
|
@ -2139,35 +2165,29 @@ class Action(Type):
|
||||||
def getDefaultLayouts(self): return {'view': 'l-f', 'edit': 'lrv-f'}
|
def getDefaultLayouts(self): return {'view': 'l-f', 'edit': 'lrv-f'}
|
||||||
def __call__(self, obj):
|
def __call__(self, obj):
|
||||||
'''Calls the action on p_obj.'''
|
'''Calls the action on p_obj.'''
|
||||||
try:
|
if type(self.action) in sequenceTypes:
|
||||||
if type(self.action) in sequenceTypes:
|
# There are multiple Python methods
|
||||||
# There are multiple Python methods
|
res = [True, '']
|
||||||
res = [True, '']
|
for act in self.action:
|
||||||
for act in self.action:
|
actRes = act(obj)
|
||||||
actRes = act(obj)
|
|
||||||
if type(actRes) in sequenceTypes:
|
|
||||||
res[0] = res[0] and actRes[0]
|
|
||||||
if self.result.startswith('file'):
|
|
||||||
res[1] = res[1] + actRes[1]
|
|
||||||
else:
|
|
||||||
res[1] = res[1] + '\n' + actRes[1]
|
|
||||||
else:
|
|
||||||
res[0] = res[0] and actRes
|
|
||||||
else:
|
|
||||||
# There is only one Python method
|
|
||||||
actRes = self.action(obj)
|
|
||||||
if type(actRes) in sequenceTypes:
|
if type(actRes) in sequenceTypes:
|
||||||
res = list(actRes)
|
res[0] = res[0] and actRes[0]
|
||||||
|
if self.result.startswith('file'):
|
||||||
|
res[1] = res[1] + actRes[1]
|
||||||
|
else:
|
||||||
|
res[1] = res[1] + '\n' + actRes[1]
|
||||||
else:
|
else:
|
||||||
res = [actRes, '']
|
res[0] = res[0] and actRes
|
||||||
# If res is None (ie the user-defined action did not return
|
else:
|
||||||
# anything), we consider the action as successfull.
|
# There is only one Python method
|
||||||
if res[0] == None: res[0] = True
|
actRes = self.action(obj)
|
||||||
except Exception, e:
|
if type(actRes) in sequenceTypes:
|
||||||
res = (False, 'An error occurred. %s' % str(e))
|
res = list(actRes)
|
||||||
obj.log(Traceback.get(), type='error')
|
else:
|
||||||
#import transaction
|
res = [actRes, '']
|
||||||
#transaction.abort()
|
# If res is None (ie the user-defined action did not return anything),
|
||||||
|
# we consider the action as successfull.
|
||||||
|
if res[0] == None: res[0] = True
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def isShowable(self, obj, layoutType):
|
def isShowable(self, obj, layoutType):
|
||||||
|
|
|
@ -511,7 +511,7 @@ class ToolClassDescriptor(ClassDescriptor):
|
||||||
fieldName = 'resultColumnsFor%s' % className
|
fieldName = 'resultColumnsFor%s' % className
|
||||||
fieldType = gen.String(multiplicity=(0,None), validator=gen.Selection(
|
fieldType = gen.String(multiplicity=(0,None), validator=gen.Selection(
|
||||||
'_appy_getAllFields*%s' % className), page='userInterface',
|
'_appy_getAllFields*%s' % className), page='userInterface',
|
||||||
group=classDescr.klass.__name__)
|
group=classDescr.klass.__name__, default=['title'])
|
||||||
self.addField(fieldName, fieldType)
|
self.addField(fieldName, fieldType)
|
||||||
|
|
||||||
def addSearchRelatedFields(self, classDescr):
|
def addSearchRelatedFields(self, classDescr):
|
||||||
|
|
|
@ -254,7 +254,8 @@ class Tool(ModelClass):
|
||||||
translations = gen.Ref(Translation, multiplicity=(0,None), add=False,
|
translations = gen.Ref(Translation, multiplicity=(0,None), add=False,
|
||||||
link=False, show='view', page=pt,
|
link=False, show='view', page=pt,
|
||||||
back=gen.Ref(attribute='trToTool', show=False))
|
back=gen.Ref(attribute='trToTool', show=False))
|
||||||
loadTranslationsAtStartup = gen.Boolean(default=True, show=False, page=pt)
|
loadTranslationsAtStartup = gen.Boolean(default=True, show=False, page=pt,
|
||||||
|
layouts='f')
|
||||||
pages = gen.Ref(Page, multiplicity=(0,None), add=True, link=False,
|
pages = gen.Ref(Page, multiplicity=(0,None), add=True, link=False,
|
||||||
show='view', back=gen.Ref(attribute='toTool3', show=False),
|
show='view', back=gen.Ref(attribute='toTool3', show=False),
|
||||||
page=gen.Page('pages', show=isManager))
|
page=gen.Page('pages', show=isManager))
|
||||||
|
|
|
@ -17,8 +17,7 @@ tfw = {"edit":"f","cell":"f","view":"f"} # Layout for Translation fields
|
||||||
<!Group!>
|
<!Group!>
|
||||||
<!Translation!>
|
<!Translation!>
|
||||||
<!Page!>
|
<!Page!>
|
||||||
Page.pages.klass = Page
|
autoref(Page, Page.pages)
|
||||||
setattr(Page, Page.pages.back.attribute, Page.pages.back)
|
|
||||||
|
|
||||||
<!Tool!>
|
<!Tool!>
|
||||||
<!wrappers!>
|
<!wrappers!>
|
||||||
|
|
Loading…
Reference in a new issue