[gen] Calendar field: added the possibility to define eventTypes dynamically: eventTypes can therefore be anything, ie object UIDs.
This commit is contained in:
parent
9954edf71a
commit
856cda9031
|
@ -1,4 +1,5 @@
|
||||||
# ------------------------------------------------------------------------------
|
# ------------------------------------------------------------------------------
|
||||||
|
import types
|
||||||
from appy import Object
|
from appy import Object
|
||||||
from appy.gen import Type
|
from appy.gen import Type
|
||||||
from DateTime import DateTime
|
from DateTime import DateTime
|
||||||
|
@ -10,20 +11,31 @@ class Calendar(Type):
|
||||||
'''This field allows to produce an agenda and view/edit events on it.'''
|
'''This field allows to produce an agenda and view/edit events on it.'''
|
||||||
jsFiles = {'view': ('widgets/calendar.js',)}
|
jsFiles = {'view': ('widgets/calendar.js',)}
|
||||||
|
|
||||||
def __init__(self, eventTypes, validator=None, default=None, show='view',
|
def __init__(self, eventTypes, eventNameMethod=None, validator=None,
|
||||||
page='main', group=None, layouts=None, move=0,
|
default=None, show='view', page='main', group=None,
|
||||||
specificReadPermission=False, specificWritePermission=False,
|
layouts=None, move=0, specificReadPermission=False,
|
||||||
width=None, height=300, colspan=1, master=None,
|
specificWritePermission=False, width=None, height=300,
|
||||||
masterValue=None, focus=False, mapping=None, label=None,
|
colspan=1, master=None, masterValue=None, focus=False,
|
||||||
maxEventLength=50, otherCalendars=None):
|
mapping=None, label=None, maxEventLength=50,
|
||||||
|
otherCalendars=None):
|
||||||
Type.__init__(self, validator, (0,1), None, default, False, False,
|
Type.__init__(self, validator, (0,1), None, default, False, False,
|
||||||
show, page, group, layouts, move, False, False,
|
show, page, group, layouts, move, False, False,
|
||||||
specificReadPermission, specificWritePermission,
|
specificReadPermission, specificWritePermission,
|
||||||
width, height, None, colspan, master, masterValue, focus,
|
width, height, None, colspan, master, masterValue, focus,
|
||||||
False, True, mapping, label)
|
False, True, mapping, label)
|
||||||
# eventTypes is a list of strings that identify the types of events
|
# eventTypes can be a "static" list or tuple of strings that identify
|
||||||
# that are supported by this calendar.
|
# the types of events that are supported by this calendar. It can also
|
||||||
|
# be a method that computes such a "dynamic" list or tuple. When
|
||||||
|
# specifying a static list, an i18n label will be generated for every
|
||||||
|
# event type of the list. When specifying a dynamic list, you must also
|
||||||
|
# give, in p_eventNameMethod, a method that will accept a single arg
|
||||||
|
# (=one of the event types from your dynamic list) and return the "name"
|
||||||
|
# of this event as it must be shown to the user.
|
||||||
self.eventTypes = eventTypes
|
self.eventTypes = eventTypes
|
||||||
|
self.eventNameMethod = eventNameMethod
|
||||||
|
if (type(eventTypes) == types.FunctionType) and not eventNameMethod:
|
||||||
|
raise Exception("When param 'eventTypes' is a method, you must " \
|
||||||
|
"give another method in param 'eventNameMethod'.")
|
||||||
# It is not possible to create events that span more days than
|
# It is not possible to create events that span more days than
|
||||||
# maxEventLength.
|
# maxEventLength.
|
||||||
self.maxEventLength = maxEventLength
|
self.maxEventLength = maxEventLength
|
||||||
|
@ -105,6 +117,14 @@ class Calendar(Type):
|
||||||
res[i][1] = res[i][0].getField(res[i][1])
|
res[i][1] = res[i][0].getField(res[i][1])
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getEventTypes(self, obj):
|
||||||
|
'''Returns the (dynamic or static) event types as defined in
|
||||||
|
self.eventTypes.'''
|
||||||
|
if type(self.eventTypes) == types.FunctionType:
|
||||||
|
return self.eventTypes(obj.appy())
|
||||||
|
else:
|
||||||
|
return self.eventTypes
|
||||||
|
|
||||||
def getEventsAt(self, obj, date, asDict=True):
|
def getEventsAt(self, obj, date, asDict=True):
|
||||||
'''Returns the list of events that exist at some p_date (=day).'''
|
'''Returns the list of events that exist at some p_date (=day).'''
|
||||||
if not hasattr(obj, self.name): return
|
if not hasattr(obj, self.name): return
|
||||||
|
@ -138,11 +158,19 @@ class Calendar(Type):
|
||||||
events = field.getEventsAt(o.o, date, asDict=False)
|
events = field.getEventsAt(o.o, date, asDict=False)
|
||||||
if events:
|
if events:
|
||||||
eventType = events[0].eventType
|
eventType = events[0].eventType
|
||||||
label = '%s_event_%s' % (field.labelId, eventType)
|
eventName = field.getEventName(o.o, eventType)
|
||||||
info = Object(name=obj.translate(label), color=color)
|
info = Object(name=eventName, color=color)
|
||||||
res.append(info.__dict__)
|
res.append(info.__dict__)
|
||||||
return res
|
return res
|
||||||
|
|
||||||
|
def getEventName(self, obj, eventType):
|
||||||
|
'''Gets the name of the event corresponding to p_eventType as it must
|
||||||
|
appear to the user.'''
|
||||||
|
if self.eventNameMethod:
|
||||||
|
return self.eventNameMethod(obj.appy(), eventType)
|
||||||
|
else:
|
||||||
|
return obj.translate('%s_event_%s' % (self.labelId, eventType))
|
||||||
|
|
||||||
def createEvent(self, obj, date, handleEventSpan=True):
|
def createEvent(self, obj, date, handleEventSpan=True):
|
||||||
'''Create a new event in the calendar, at some p_date (day). If
|
'''Create a new event in the calendar, at some p_date (day). If
|
||||||
p_handleEventSpan is True, we will use rq["eventSpan"] and also
|
p_handleEventSpan is True, we will use rq["eventSpan"] and also
|
||||||
|
|
|
@ -380,6 +380,8 @@ class FieldDescriptor:
|
||||||
|
|
||||||
def walkCalendar(self):
|
def walkCalendar(self):
|
||||||
# Add i18n-specific messages
|
# Add i18n-specific messages
|
||||||
|
eTypes = self.appyType.eventTypes
|
||||||
|
if not isinstance(eTypes, list) and not isinstance(eTypes, tuple):return
|
||||||
for et in self.appyType.eventTypes:
|
for et in self.appyType.eventTypes:
|
||||||
label = '%s_%s_event_%s' % (self.classDescr.name,self.fieldName,et)
|
label = '%s_%s_event_%s' % (self.classDescr.name,self.fieldName,et)
|
||||||
msg = PoMessage(label, '', et)
|
msg = PoMessage(label, '', et)
|
||||||
|
|
|
@ -71,7 +71,7 @@
|
||||||
<tal:comment replace="nothing">A single event is allowed for the moment</tal:comment>
|
<tal:comment replace="nothing">A single event is allowed for the moment</tal:comment>
|
||||||
<div tal:define="eventType python: events[0]['eventType']">
|
<div tal:define="eventType python: events[0]['eventType']">
|
||||||
<span style="color: grey"
|
<span style="color: grey"
|
||||||
tal:content="python: _('%s_event_%s' % (widget['labelId'], eventType))"></span>
|
tal:content="python: contextObj.callField(fieldName, 'getEventName', contextObj, eventType)"></span>
|
||||||
</div>
|
</div>
|
||||||
</tal:events>
|
</tal:events>
|
||||||
<tal:comment replace="nothing">Events from other calendars</tal:comment>
|
<tal:comment replace="nothing">Events from other calendars</tal:comment>
|
||||||
|
@ -102,8 +102,8 @@
|
||||||
|
|
||||||
<div align="center" style="margin-bottom: 3px" tal:content="python: _('which_event')"></div>
|
<div align="center" style="margin-bottom: 3px" tal:content="python: _('which_event')"></div>
|
||||||
<select name="eventType">
|
<select name="eventType">
|
||||||
<option tal:repeat="eventType widget/eventTypes"
|
<option tal:repeat="eventType python: contextObj.callField(fieldName, 'getEventTypes', contextObj)"
|
||||||
tal:content="python: _('%s_event_%s' % (widget['labelId'], eventType))"
|
tal:content="python: contextObj.callField(fieldName, 'getEventName', contextObj, eventType)"
|
||||||
tal:attributes="value eventType">
|
tal:attributes="value eventType">
|
||||||
</option>
|
</option>
|
||||||
</select><br/><br/>
|
</select><br/><br/>
|
||||||
|
|
Loading…
Reference in a new issue