diff --git a/__init__.py b/__init__.py index 91788e0..17489b5 100644 --- a/__init__.py +++ b/__init__.py @@ -40,9 +40,13 @@ class Object: def get(self, name, default=None): return getattr(self, name, default) def __getitem__(self, k): return getattr(self, k) def update(self, other): - '''Includes information from p_other into p_self.''' + '''Includes information from p_other into p_self''' for k, v in other.__dict__.iteritems(): setattr(self, k, v) + def clone(self): + res = Object() + res.update(self) + return res # ------------------------------------------------------------------------------ class Hack: diff --git a/fields/calendar.py b/fields/calendar.py index 36b323e..03df3cc 100644 --- a/fields/calendar.py +++ b/fields/calendar.py @@ -89,7 +89,7 @@ class Calendar(Field): var2="events=field.getEventsAt(zobj, date); spansDays=field.hasEventsAt(zobj, date+1, events); mayCreate=mayEdit and not events; - mayDelete=mayEdit and events; + mayDelete=mayEdit and events and field.mayDelete(obj,events); day=date.day(); dayString=date.strftime('%Y/%m/%d'); js=mayEdit and 'toggleVisibility(this, %s)' % q('img') \ @@ -216,7 +216,7 @@ class Calendar(Field): mapping=None, label=None, maxEventLength=50, otherCalendars=None, additionalInfo=None, startDate=None, endDate=None, defaultDate=None, preCompute=None, - applicableEvents=None, view=None, xml=None): + applicableEvents=None, view=None, xml=None, delete=True): Field.__init__(self, validator, (0,1), default, show, page, group, layouts, move, False, True, False, specificReadPermission, specificWritePermission, width, height, None, colspan, @@ -294,6 +294,9 @@ class Calendar(Field): # for explaining him why he can, for this day, only create events of a # sub-set of the possible event types (or even no event at all). self.applicableEvents = applicableEvents + # May the user delete events in this calendar? If "delete" is a method, + # it must accept an event type as single arg. + self.delete = delete def getPreComputedInfo(self, obj, monthDayOne, grid): '''Returns the result of calling self.preComputed, or None if no such @@ -573,9 +576,9 @@ class Calendar(Field): eventSpan = rq.get('eventSpan', None) # Split the p_date into separate parts year, month, day = date.year(), date.month(), date.day() - # Check that the "preferences" dict exists or not. + # Check that the "preferences" dict exists or not if not hasattr(obj.aq_base, self.name): - # 1st level: create a IOBTree whose keys are years. + # 1st level: create a IOBTree whose keys are years setattr(obj, self.name, IOBTree()) yearsDict = getattr(obj, self.name) # Get the sub-dict storing months for a given year @@ -593,7 +596,7 @@ class Calendar(Field): events = daysDict[day] else: daysDict[day] = events = PersistentList() - # Create and store the event, excepted if an event already exists. + # Create and store the event, excepted if an event already exists if not events: event = Object(eventType=eventType) events.append(event) @@ -604,6 +607,12 @@ class Calendar(Field): date = date + 1 self.createEvent(obj, date, handleEventSpan=False) + def mayDelete(self, obj, events): + '''May the user delete p_events?''' + if not self.delete: return + if callable(self.delete): return self.delete(obj, events[0].eventType) + return True + def deleteEvent(self, obj, date, handleEventSpan=True): '''Deletes an event. It actually deletes all events at p_date. If p_handleEventSpan is True, we will use rq["deleteNext"] to diff --git a/fields/group.py b/fields/group.py index 8d71fc6..540f2b2 100644 --- a/fields/group.py +++ b/fields/group.py @@ -179,7 +179,7 @@ class Group: return uiGroup class Column: - '''Used for describing a column within a Group like defined above.''' + '''Used for describing a column within a Group like defined above''' def __init__(self, width, align="left"): self.width = width self.align = align diff --git a/fields/list.py b/fields/list.py index 93b9eb5..b709808 100644 --- a/fields/list.py +++ b/fields/list.py @@ -22,9 +22,11 @@ from appy.gen.layout import Table # ------------------------------------------------------------------------------ class List(Field): - '''A list.''' + '''A list, stored as a list of Object instances ~[Object]~. Every object in + the list has attributes named according to the sub-fields defined in this + List.''' - # PX for rendering a single row. + # PX for rendering a single row pxRow = Px('''
''') - # PX for rendering the list (shared between pxView and pxEdit). + # PX for rendering the list (shared between pxView and pxEdit) pxTable = Px('''