diff --git a/fields/calendar.py b/fields/calendar.py
index a8e3897..9c19edf 100644
--- a/fields/calendar.py
+++ b/fields/calendar.py
@@ -93,6 +93,10 @@ class Other:
info.name = eventNames[eventType]
res.append(info)
+ def mayValidate(self):
+ '''Is validation enabled for this other calendar?'''
+ return self.field.mayValidate(self.obj)
+
# ------------------------------------------------------------------------------
class Event(Persistent):
'''An event as will be stored in the database'''
@@ -159,19 +163,15 @@ class Calendar(Field):
# Legend for a timeline calendar
pxTimelineLegend = Px('''
@@ -682,11 +683,63 @@ class Calendar(Field):
return '%s' % (other.obj.url, other.obj.title)
return self.timelineName(self, other)
- def getTimelineCell(self, events):
- '''Gets the content of a cell in a timeline calendar.'''
- # Currently a single event is allowed
- if not events or not events[0].symbol: return ''
- return events[0].symbol
+ def getTimelineCell(self, date, other, events, mayValidate):
+ '''Gets the content of a cell in a timeline calendar'''
+ if events and mayValidate:
+ # If at least one event from p_events is in the validation schema,
+ # propose a unique checkbox, that will allow to validate or not all
+ # validable events at p_date.
+ for info in events:
+ if info.event.eventType in other.field.validation.schema:
+ return ''
+ return ''
+ # When there are multiple events, a background image is already shown
+ if not events or (len(events) > 1): return ''
+ # A single event: if not colored, show a symbol
+ return events[0].symbol or ''
+
+ def getLegendItems(self, allEventTypes, allEventNames, colors, url, _):
+ '''Gets information needed to produce the legend for a timeline.'''
+ # Produce one legend item by event type shown and colored
+ res = []
+ for eventType in allEventTypes:
+ if eventType not in colors: continue
+ res.append(Object(name=allEventNames[eventType],
+ style='background-color: %s' % colors[eventType]))
+ # Add the background indicating that several events are hidden behind
+ # the timeline cell
+ res.append(Object(name=_('several_events'),
+ style=url('angled', bg=True)))
+ return res
+
+ def getTimelineMonths(self, grid, obj):
+ '''Given the p_grid of dates, this method returns the list of
+ corresponding months.'''
+ res = []
+ for date in grid:
+ if not res:
+ # Get the month correspoding to the first day in the grid
+ m = Object(month=date.aMonth(), colspan=1, year=date.year())
+ res.append(m)
+ else:
+ # Augment current month' colspan or create a new one
+ current = res[-1]
+ if date.aMonth() == current.month:
+ current.colspan += 1
+ else:
+ m = Object(month=date.aMonth(), colspan=1, year=date.year())
+ res.append(m)
+ # Replace month short names by translated names whose format may vary
+ # according to colspan (a higher colspan allow us to produce a longer
+ # month name).
+ for m in res:
+ text = '%s %d' % (obj.translate('month_%s' % m.month), m.year)
+ if m.colspan < 6:
+ # Short version: a single letter with an acronym
+ m.month = '%s' % (text, text[0])
+ else:
+ m.month = text
+ return res
def getAdditionalInfoAt(self, obj, date, preComputed):
'''If the user has specified a method in self.additionalInfo, we call
@@ -1144,9 +1197,15 @@ class Calendar(Field):
def getCellStyle(self, obj, date, render, events):
'''Gets the cell style to apply to the cell corresponding to p_date.'''
if render != 'timeline': return '' # Currently, for timelines only
- if not events or (len(events) > 1): return ''
- event = events[0]
- return event.bgColor and ('background-color: %s' % event.bgColor) or ''
+ if not events: return ''
+ elif len(events) > 1:
+ # Return a special background indicating that several events are
+ # hidden behing this cell.
+ return 'background-image: url(%s/ui/angled.png)' % \
+ obj.getTool().getSiteUrl()
+ else:
+ event = events[0]
+ return event.bgColor and ('background-color: %s' % event.bgColor) or ''
def getCellClass(self, obj, date, render, today):
'''What CSS class(es) must apply to the table cell representing p_date
@@ -1163,35 +1222,6 @@ class Calendar(Field):
res.append('cellDashed')
return ' '.join(res)
- def getTimelineMonths(self, grid, obj):
- '''Given the p_grid of dates, this method returns the list of
- corresponding months.'''
- res = []
- for date in grid:
- if not res:
- # Get the month correspoding to the first day in the grid
- m = Object(month=date.aMonth(), colspan=1, year=date.year())
- res.append(m)
- else:
- # Augment current month' colspan or create a new one
- current = res[-1]
- if date.aMonth() == current.month:
- current.colspan += 1
- else:
- m = Object(month=date.aMonth(), colspan=1, year=date.year())
- res.append(m)
- # Replace month short names by translated names whose format may vary
- # according to colspan (a higher colspan allow us to produce a longer
- # month name).
- for m in res:
- text = '%s %d' % (obj.translate('month_%s' % m.month), m.year)
- if m.colspan < 6:
- # Short version: a single letter with an acronym
- m.month = '%s' % (text, text[0])
- else:
- m.month = text
- return res
-
def splitList(self, l, sub): return sutils.splitList(l, sub)
def mayValidate(self, obj):
'''May the currently logged user validate wish events ?'''
diff --git a/gen/tr/Appy.pot b/gen/tr/Appy.pot
index ae4c2d4..9a338be 100644
--- a/gen/tr/Appy.pot
+++ b/gen/tr/Appy.pot
@@ -715,6 +715,10 @@ msgstr ""
msgid "del_next_events"
msgstr ""
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/tr/ar.po b/gen/tr/ar.po
index 52b19fd..7dfb33f 100644
--- a/gen/tr/ar.po
+++ b/gen/tr/ar.po
@@ -715,6 +715,10 @@ msgstr ""
msgid "del_next_events"
msgstr ""
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/tr/de.po b/gen/tr/de.po
index 5d1918b..a849676 100644
--- a/gen/tr/de.po
+++ b/gen/tr/de.po
@@ -715,6 +715,10 @@ msgstr ""
msgid "del_next_events"
msgstr ""
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/tr/en.po b/gen/tr/en.po
index e3e0608..aa89635 100644
--- a/gen/tr/en.po
+++ b/gen/tr/en.po
@@ -716,6 +716,10 @@ msgstr "Extend the event on the following number of days (leave blank to create
msgid "del_next_events"
msgstr "Also delete successive events of the same type."
+#. Default: "Several events"
+msgid "several_events"
+msgstr "Several events"
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr "Timeslot"
diff --git a/gen/tr/es.po b/gen/tr/es.po
index e7c2023..ae36095 100644
--- a/gen/tr/es.po
+++ b/gen/tr/es.po
@@ -715,6 +715,10 @@ msgstr ""
msgid "del_next_events"
msgstr ""
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/tr/fr.po b/gen/tr/fr.po
index 108db59..f9e8ff0 100644
--- a/gen/tr/fr.po
+++ b/gen/tr/fr.po
@@ -716,6 +716,10 @@ msgstr "Étendre l'événement sur le nombre de jours suivants (laissez vide pou
msgid "del_next_events"
msgstr "Supprimer aussi les événements successifs de même type"
+#. Default: "Several events"
+msgid "several_events"
+msgstr "Plusieurs événements"
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr "Plage horaire"
diff --git a/gen/tr/it.po b/gen/tr/it.po
index 478ed73..5542c1a 100644
--- a/gen/tr/it.po
+++ b/gen/tr/it.po
@@ -715,6 +715,10 @@ msgstr ""
msgid "del_next_events"
msgstr ""
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/tr/nl.po b/gen/tr/nl.po
index 033b841..34d3527 100644
--- a/gen/tr/nl.po
+++ b/gen/tr/nl.po
@@ -715,6 +715,10 @@ msgstr "Het event uitbreiden naar de volgende dagen (leeg laten om een event aan
msgid "del_next_events"
msgstr "Verwijder ook alle opeenvolgende events van hetzelfde type"
+#. Default: "Several events"
+msgid "several_events"
+msgstr ""
+
#. Default: "Timeslot"
msgid "timeslot"
msgstr ""
diff --git a/gen/ui/angled.png b/gen/ui/angled.png
new file mode 100644
index 0000000..685a491
Binary files /dev/null and b/gen/ui/angled.png differ