From 856cda90310d5b394782011592d88642f4abc62e Mon Sep 17 00:00:00 2001 From: Gaetan Delannay Date: Fri, 12 Oct 2012 16:36:04 +0200 Subject: [PATCH] [gen] Calendar field: added the possibility to define eventTypes dynamically: eventTypes can therefore be anything, ie object UIDs. --- gen/calendar.py | 48 ++++++++++++++++++++++++++++++-------- gen/descriptors.py | 2 ++ gen/ui/widgets/calendar.pt | 6 ++--- 3 files changed, 43 insertions(+), 13 deletions(-) diff --git a/gen/calendar.py b/gen/calendar.py index 3b52e6b..348060e 100644 --- a/gen/calendar.py +++ b/gen/calendar.py @@ -1,4 +1,5 @@ # ------------------------------------------------------------------------------ +import types from appy import Object from appy.gen import Type from DateTime import DateTime @@ -10,20 +11,31 @@ class Calendar(Type): '''This field allows to produce an agenda and view/edit events on it.''' jsFiles = {'view': ('widgets/calendar.js',)} - def __init__(self, eventTypes, validator=None, default=None, show='view', - page='main', group=None, layouts=None, move=0, - specificReadPermission=False, specificWritePermission=False, - width=None, height=300, colspan=1, master=None, - masterValue=None, focus=False, mapping=None, label=None, - maxEventLength=50, otherCalendars=None): + def __init__(self, eventTypes, eventNameMethod=None, validator=None, + default=None, show='view', page='main', group=None, + layouts=None, move=0, specificReadPermission=False, + specificWritePermission=False, width=None, height=300, + colspan=1, master=None, masterValue=None, focus=False, + mapping=None, label=None, maxEventLength=50, + otherCalendars=None): Type.__init__(self, validator, (0,1), None, default, False, False, show, page, group, layouts, move, False, False, specificReadPermission, specificWritePermission, width, height, None, colspan, master, masterValue, focus, False, True, mapping, label) - # eventTypes is a list of strings that identify the types of events - # that are supported by this calendar. + # eventTypes can be a "static" list or tuple of strings that identify + # 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.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 # maxEventLength. self.maxEventLength = maxEventLength @@ -105,6 +117,14 @@ class Calendar(Type): res[i][1] = res[i][0].getField(res[i][1]) 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): '''Returns the list of events that exist at some p_date (=day).''' if not hasattr(obj, self.name): return @@ -138,11 +158,19 @@ class Calendar(Type): events = field.getEventsAt(o.o, date, asDict=False) if events: eventType = events[0].eventType - label = '%s_event_%s' % (field.labelId, eventType) - info = Object(name=obj.translate(label), color=color) + eventName = field.getEventName(o.o, eventType) + info = Object(name=eventName, color=color) res.append(info.__dict__) 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): '''Create a new event in the calendar, at some p_date (day). If p_handleEventSpan is True, we will use rq["eventSpan"] and also diff --git a/gen/descriptors.py b/gen/descriptors.py index 627ec04..91ad672 100644 --- a/gen/descriptors.py +++ b/gen/descriptors.py @@ -380,6 +380,8 @@ class FieldDescriptor: def walkCalendar(self): # 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: label = '%s_%s_event_%s' % (self.classDescr.name,self.fieldName,et) msg = PoMessage(label, '', et) diff --git a/gen/ui/widgets/calendar.pt b/gen/ui/widgets/calendar.pt index 0d47c3d..2138803 100644 --- a/gen/ui/widgets/calendar.pt +++ b/gen/ui/widgets/calendar.pt @@ -71,7 +71,7 @@ A single event is allowed for the moment
+ tal:content="python: contextObj.callField(fieldName, 'getEventName', contextObj, eventType)">
Events from other calendars @@ -102,8 +102,8 @@