Welcome | Get started | Dive | Contribute | Topics | Reference | Changes | More
calview : Calendar view¶
The lino_xl.lib.calview plugin adds a calendar view.
This page contains code snippets (lines starting with >>>), which are
being tested during our development workflow. The following
snippet initializes the demo project used throughout this page.
>>> from lino_book.projects.avanti1.startup import *
>>> ar = rt.login("robin")
Good to know¶
A few things you should know before modifying the code:
Play through our manual testing suite The calendar views before and after your changes.
A calendar planner is actually a set of up to three calendar views (daily, weekly, monthly).
A calendar view a data table that is always in detail mode (its
get_default_action()returns self.detail_action). We never use a calendar view in any other display mode).The detail window of a calendar view has a parameter panel because use_detail_param_panel is True (normally the detail view has no parameter panel). The parameter panel is on the left because
params_panel_posis ‘left’.The detail layout itself (on the right) contains a single data element, which is a slave table. This slave table is either daily, weekly or monthly. It’s the only part that varies between the calendar views.
The daily and weekly views have in common that they show one row per DailyPlannerRow (usually “AM” and “PM”, but that’s configurable into other time slices).
ParameterClone is not only used by the 3 calendar master views and the 3 calendar slave views, but also by the independent table DailyPlanner, which is used as dashboard item.
In presto1 we have two calendar views: the normal “Calendar” and the “Workers planner”. The latter uses the workers table instead of the usual DailyPlannerRow.
In noi1r, clone_parameters_from is set to working.Sessions instead of its usual value cal.Events.
Multiple “planners”¶
The “Calendar” quicklink comes from the Planners choicelist, which
usually has only one choice:
>>> rt.show(calview.Planners)
========= ========= ========== ===================== ==================== ===================
value name text Monthly view Weekly view Daily view
--------- --------- ---------- --------------------- -------------------- -------------------
default default Calendar calview.MonthlyView calview.WeeklyView calview.DailyView
========= ========= ========== ===================== ==================== ===================
But e.g. in Presto it has a second choice. See The Calendar plugin in Presto.
Calendar views¶
- class lino_xl.lib.calview.CalendarView¶
Base class for all calendar views.
A calendar view is a virtual table that opens in detail view by default, the grid view is useless.
The detail of a calendar view varies, but it usually shows at least one slave table, which is usually a subclass of
DaySlave.
- class lino_xl.lib.calview.DailyView¶
Shows a calendar navigator with a configurable daily view.
Inherits from
CalendarView.- insert_event¶
Custom action for inserting a calendar entry in the DailyView.
Returns an eval_js that equates to running the insert window action for Events with the correct known values.
- class lino_xl.lib.calview.WeeklyView¶
Shows a calendar navigator with a configurable weekly view.
Inherits from
CalendarView.
- class lino_xl.lib.calview.MonthlyView¶
Shows a calendar navigator with a configurable monthly view.
Inherits from
CalendarView.
The calendar views¶
The calendar views use an instance of Day as master instance. That’s a
light-weight object representing a given date, with a primary key that is an
integer representing the offset relative to today.
>>> day = calview.WeeklyView.get_row_by_pk(ar, -6)
>>> day.__class__
<class 'lino_xl.lib.calview.mixins.Day'>
>>> day
<Day(-6=2017-02-09)>
>>> day.date
datetime.date(2017, 2, 9)
>>> def showit(t, offset=0, **kwargs):
... day = t.calendar_view.get_row_by_pk(ar, offset)
... ar.show(t, master_instance=day, max_width=15, **kwargs)
>>> showit(calview.WeeklySlave)
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| Time range | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
+=================+=================+=================+=================+=================+=================+=================+=================+
| `All day <…>`__ | `13 <…>`__`[img | `14 <…>`__`[img | **`15 | `16 <…>`__`[img | `17 <…>`__`[img | `18 <…>`__`[img | `19 <…>`__`[img |
| | add] <…>`__ | add] <…>`__ ` ☒ | <…>`__**`[img | add] <…>`__ ` | add] <…>`__ | add] <…>`__ | add] <…>`__ |
| | | romain Absent | add] <…>`__ ` | ☐ Absent for | ` ? romain | ` ☐ rolf | ` ? Absent |
| | | for private | ☑ rolf Absent | private reasons | Absent for | Absent for | for private |
| | | reasons <…>`__ | for private | <…>`__ | private reasons | private reasons | reasons <…>`__ |
| | | | reasons <…>`__ | | <…>`__ | <…>`__ | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `AM <…>`__ | ` 09:00 ? laura | ` 09:00 ? laura | ` 08:30 ☑ | ` 09:00 ? laura | ` 09:00 ? laura | | ` 08:30 ? |
| | Alphabetisation | Alphabetisation | romain Réunion | Alphabetisation | Alphabetisation | | Interview |
| | (16/01/2017) | (16/01/2017) | <…>`__ | (16/01/2017) | (16/01/2017) | | <…>`__` 09:40 ☐ |
| | Lesson 17 | Lesson 18 | | Lesson 19 | Lesson 20 | | romain Diner |
| | <…>`__` 09:40 ☑ | <…>`__` 11:10 ☑ | | <…>`__` 09:40 ? | <…>`__` 10:20 ☐ | | <…>`__ |
| | Interview | rolf Abendessen | | rolf Beratung | Seminar | | |
| | <…>`__` 10:20 ☒ | <…>`__ | | <…>`__ | <…>`__` 11:10 ? | | |
| | romain Diner | | | | romain | | |
| | <…>`__ | | | | Evaluation | | |
| | | | | | <…>`__ | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `PM <…>`__ | ` 14:00 ? laura | ` 14:00 ? laura | ` 13:30 ☒ | ` 14:00 ? laura | ` 14:00 ? laura | ` 13:30 ☐ rolf | |
| | Alphabetisation | Alphabetisation | Breakfast | Alphabetisation | Alphabetisation | Erstgespräch | |
| | (16/01/2017) | (16/01/2017) | <…>`__ | (16/01/2017) | (16/01/2017) | <…>`__ | |
| | Lesson 17 | Lesson 18 | | Lesson 19 | Lesson 20 | | |
| | <…>`__` 18:00 ? | <…>`__` 18:00 ? | | <…>`__` 18:00 ? | <…>`__` 18:00 ? | | |
| | laura | laura | | laura | laura | | |
| | Alphabetisation | Alphabetisation | | Alphabetisation | Alphabetisation | | |
| | (16/01/2017) | (16/01/2017) | | (16/01/2017) | (16/01/2017) | | |
| | Lesson 17 | Lesson 18 | | Lesson 19 | Lesson 20 | | |
| | <…>`__ | <…>`__ | | <…>`__ | <…>`__ | | |
+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
>>> showit(calview.MonthlySlave)
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| Week | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
+===========+=================+=================+=================+=================+=================+=================+=================+
| `5 <…>`__ | `30 <…>`__`[img | `31 <…>`__`[img | `1 <…>`__`[img | `2 <…>`__`[img | `3 <…>`__`[img | `4 <…>`__`[img | `5 <…>`__`[img |
| | add] | add] <…>`__ | add] | add] <…>`__ | add] | add] <…>`__ | add] |
| | <…>`__` 08:30 ☒ | | <…>`__` 11:10 ☑ | | <…>`__` 09:40 ☒ | | <…>`__` 13:30 ☑ |
| | Seminar <…>`__ | | Interview | | Breakfast | | Seminar <…>`__ |
| | | | <…>`__ | | <…>`__ | | |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `6 <…>`__ | `6 <…>`__`[img | `7 <…>`__`[img | `8 <…>`__`[img | `9 <…>`__`[img | `10 <…>`__`[img | `11 <…>`__`[img | `12 <…>`__`[img |
| | add] <…>`__ | add] | add] <…>`__ | add] | add] <…>`__ | add] | add] <…>`__ |
| | | <…>`__` 10:20 ☒ | | <…>`__` 08:30 ☑ | | <…>`__` 11:10 ☒ | |
| | | Interview | | Breakfast | | Seminar <…>`__ | |
| | | <…>`__ | | <…>`__ | | | |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `7 <…>`__ | `13 <…>`__`[img | `14 <…>`__`[img | **`15 | `16 <…>`__`[img | `17 <…>`__`[img | `18 <…>`__`[img | `19 <…>`__`[img |
| | add] | add] <…>`__ | <…>`__**`[img | add] <…>`__` ☐ | add] | add] <…>`__ | add] <…>`__ ` ? |
| | <…>`__` 09:40 ☑ | | add] | Absent for | <…>`__ ` 10:20 | | Absent for |
| | Interview | | <…>`__` 13:30 ☒ | private reasons | ☐ Seminar | | private reasons |
| | <…>`__ | | Breakfast | <…>`__ | <…>`__ | | <…>`__` 08:30 ? |
| | | | <…>`__ | | | | Interview |
| | | | | | | | <…>`__ |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `8 <…>`__ | `20 <…>`__`[img | `21 <…>`__`[img | `22 <…>`__`[img | `23 <…>`__`[img | `24 <…>`__`[img | `25 <…>`__`[img | `26 <…>`__`[img |
| | add] <…>`__` | add] | add] <…>`__ ` ☐ | add] | add] <…>`__ | add] | add] <…>`__ |
| | <…>`__ | <…>`__ ` 11:10 | Absent for | <…>`__ ` 09:40 | | <…>`__ ` 13:30 | |
| | | ☐ Breakfast | private reasons | ? Seminar | | ☐ Interview | |
| | | <…>`__ | <…>`__ | <…>`__ | | <…>`__ | |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
| `9 <…>`__ | `27 <…>`__`[img | `28 <…>`__`[img | `1 <…>`__`[img | `2 <…>`__`[img | `3 <…>`__`[img | `4 <…>`__`[img | `5 <…>`__`[img |
| | add] | add] <…>`__ | add] | add] <…>`__ | add] | add] <…>`__ | add] |
| | <…>`__` 10:20 ? | | <…>`__` 08:30 ☐ | | <…>`__` 11:10 ? | | <…>`__` 09:40 ☐ |
| | Breakfast | | Seminar <…>`__ | | Interview | | Breakfast |
| | <…>`__ | | | | <…>`__ | | <…>`__ |
+-----------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+-----------------+
>>> showit(calview.DailySlave)
+-----------------+-----------------+----------+
| Time range | External | Internal |
+=================+=================+==========+
| `All day <…>`__ | ` ☒ romain | |
| | Absent for | |
| | private reasons | |
| | <…>`__` ☑ rolf | |
| | Absent for | |
| | private reasons | |
| | <…>`__ | |
+-----------------+-----------------+----------+
| `AM <…>`__ | ` 08:30 ☑ | |
| | romain Réunion | |
| | <…>`__ | |
+-----------------+-----------------+----------+
| `PM <…>`__ | | |
+-----------------+-----------------+----------+
The daily planner¶
The daily planner is a table that shows an overview on all events of a day.
>>> showit(calview.DailyPlanner, -6)
...
+-----------------+-----------------+----------+
| Time range | External | Internal |
+=================+=================+==========+
| `All day <…>`__ | | |
+-----------------+-----------------+----------+
| `AM <…>`__ | ` 09:40 ☒ | |
| | romain Réunion | |
| | <…>`__ | |
+-----------------+-----------------+----------+
| `PM <…>`__ | | |
+-----------------+-----------------+----------+
- class lino_xl.lib.calview.DailyPlanner¶
The virtual table used to render the daily planner.
- class lino_xl.lib.calview.PlannerColumns¶
A choicelist that defines the columns to appear in the daily planner. This list can be modified locally.
A default configuration has two columns in the daily planner:
>>> rt.show(calview.PlannerColumns)
======= ========== ==========
value name text
------- ---------- ----------
10 external External
20 internal Internal
======= ========== ==========
- class lino_xl.lib.calview.DailyPlannerRow¶
A database object that represents one row of the daily planner. The default configuration has “AM”, “PM” and “All day”.
>>> rt.show(calview.DailyPlannerRows)
===== ============= ================== ================== ============ ==========
No. Designation Designation (de) Designation (fr) Start time End time
----- ------------- ------------------ ------------------ ------------ ----------
1 AM Vormittags Avant-midi 12:00:00
2 PM Nachmittags Après-midi 12:00:00
===== ============= ================== ================== ============ ==========
Utilities¶
- class lino_xl.lib.calview.Day¶
An in-memory wrapper around a datetime.date instance.
A subclass of
lino.core.fields.TableRow.- date¶
- pk¶
- ar¶
- class lino_xl.lib.calview.DaySlave¶
Table mixin for slave tables of tables on
Day.Used by both database and virtual tables.
Base class for the three calendar views, but also used for independent tables like working.WorkedHours. A virtual table whose rows are calview.Day instances. Subclasses must set navigation_mode.
Inherits from
DaysTable.
Tested translations¶
>>> with translation.override('de'):
... showit(calview.DailyPlanner, -6, header_level=1)
===========================
Donnerstag, 9. Februar 2017
===========================
+-----------------+-----------------+--------+
| Zeitabschnitt | Extern | Intern |
+=================+=================+========+
| `Ganztags | | |
| <…>`__ | | |
+-----------------+-----------------+--------+
| `Vormittags | ` 09:40 ☒ | |
| <…>`__ | romain Réunion | |
| | <…>`__ | |
+-----------------+-----------------+--------+
| `Nachmittags | | |
| <…>`__ | | |
+-----------------+-----------------+--------+
>>> showit(calview.DailyPlanner, -6, language="fr", header_level=1)
====================
jeudi 9 février 2017
====================
+-----------------+-----------------+---------+
| Time range | Externe | Interne |
+=================+=================+=========+
| `Journée | | |
| entière <…>`__ | | |
+-----------------+-----------------+---------+
| `Avant-midi | ` 09:40 ☒ | |
| <…>`__ | romain Réunion | |
| | <…>`__ | |
+-----------------+-----------------+---------+
| `Après-midi | | |
| <…>`__ | | |
+-----------------+-----------------+---------+
>>> update_guests = cal.Events.get_action_by_name('update_guests')
>>> print(update_guests.help_text)
Populate or update the list of participants for this calendar entry according to the suggestions.
>>> with translation.override('de'):
... print(str(update_guests.help_text))
...
Teilnehmerliste für diesen Kalendereintrag füllen entsprechend der Vorschläge.
>>> update_guests.help_text.__class__
...
<class 'django.utils.functional...__proxy__'>
Class inheritance¶


The Day object¶
>>> from lino_xl.lib.calview.mixins import Day
>>> modes = ('day', 'week', 'month')
>>> headers = ["Offset"] + list(modes)
>>> rows = []
>>> for offset in (0, -10, 15):
... cells = [str(offset)]
... for nm in modes:
... cells.append(str(Day(offset, ar, nm)))
... rows.append(cells)
>>> print(rstgen.table(headers, rows))
...
======== ============================= ============================= ===============
Offset day week month
-------- ----------------------------- ----------------------------- ---------------
0 Wednesday, 15 February 2017 Week 7 / 2017 (13 February) February 2017
-10 Sunday, 5 February 2017 Week 5 / 2017 (30 January) February 2017
15 Thursday, 2 March 2017 Week 9 / 2017 (27 February) March 2017
======== ============================= ============================= ===============
7 October 2015 : Wednesday or Saturday?¶
Trying to understand #5610 (calview.WeeklyView renders the weekdays wrong)
The 2015-10-07 is a Wednesday:
>>> offset = 5
>>> print(dd.today(offset))
2017-02-20
>>> day = calview.DailyView.get_row_by_pk(ar, offset)
>>> print(day)
Monday, 20 February 2017
The following is wrong. The case should fail. It should show 20 for the first column.
>>> ar.show(calview.WeeklySlave, master_instance=day, max_width=10)
+------------+------------+------------+------------+------------+------------+------------+------------+
| Time range | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
+============+============+============+============+============+============+============+============+
| `All day | `20 <…>`__ | `21 <…>`__ | `22 <…>`__ | `23 <…>`__ | `24 <…>`__ | `25 <…>`__ | `26 <…>`__ |
| <…>`__ | `[img add] | `[img add] | `[img add] | `[img add] | `[img add] | `[img add] | `[img add] |
| | <…>`__ ` ☐ | <…>`__ ` | <…>`__ ` | <…>`__ | <…>`__ | <…>`__ | <…>`__ |
| | romain | ? rolf | ☐ Absent | ` ? | | | |
| | Absent for | Absent for | for | romain | | | |
| | private | private | private | Absent for | | | |
| | reasons | reasons | reasons | private | | | |
| | <…>`__ | <…>`__ | <…>`__ | reasons | | | |
| | | | | <…>`__ | | | |
+------------+------------+------------+------------+------------+------------+------------+------------+
| `AM <…>`__ | ` 09:00 ? | ` 09:00 ? | ` 08:30 ☐ | ` 09:00 ? | ` 09:00 ? | ` 08:30 ? | ` 09:40 ☐ |
| | laura Alph | laura Alph | rolf | laura Alph | laura Alph | romain | rolf |
| | abetisatio | abetisatio | Beratung | abetisatio | abetisatio | Diner | Abendessen |
| | n (16/01/2 | n (16/01/2 | <…>`__ | n (16/01/2 | n (16/01/2 | <…>`__ | <…>`__ |
| | 017) | 017) | | 017) | 017) | | |
| | Lesson 21 | Lesson 22 | | Lesson 23 | Lesson 24 | | |
| | <…>`__` 10 | <…>`__` 11 | | <…>`__` 09 | <…>`__` 11 | | |
| | :20 ? rolf | :10 ☐ | | :40 ? | :10 ? rolf | | |
| | Abendessen | Breakfast | | Seminar <… | Erstgesprä | | |
| | <…>`__ | <…>`__ | | >`__` 10:2 | ch <…>`__ | | |
| | | | | 0 ☐ romain | | | |
| | | | | Evaluation | | | |
| | | | | <…>`__ | | | |
+------------+------------+------------+------------+------------+------------+------------+------------+
| `PM <…>`__ | ` 14:00 ? | ` 13:30 ? | | ` 14:00 ? | ` 14:00 ? | ` 13:30 ☐ | |
| | laura Alph | romain | | laura Alph | laura Alph | Interview | |
| | abetisatio | Réunion <… | | abetisatio | abetisatio | <…>`__ | |
| | n (16/01/2 | >`__` 14:0 | | n (16/01/2 | n (16/01/2 | | |
| | 017) | 0 ? laura | | 017) | 017) | | |
| | Lesson 21 | Alphabetis | | Lesson 23 | Lesson 24 | | |
| | <…>`__` 18 | ation (16/ | | <…>`__` 18 | <…>`__` 18 | | |
| | :00 ? | 01/2017) | | :00 ? | :00 ? | | |
| | laura Alph | Lesson 22 | | laura Alph | laura Alph | | |
| | abetisatio | <…>`__` 18 | | abetisatio | abetisatio | | |
| | n (16/01/2 | :00 ? | | n (16/01/2 | n (16/01/2 | | |
| | 017) | laura Alph | | 017) | 017) | | |
| | Lesson 21 | abetisatio | | Lesson 23 | Lesson 24 | | |
| | <…>`__ | n (16/01/2 | | <…>`__ | <…>`__ | | |
| | | 017) | | | | | |
| | | Lesson 22 | | | | | |
| | | <…>`__ | | | | | |
+------------+------------+------------+------------+------------+------------+------------+------------+
Plugin settings¶
- lino_xl.lib.calview.params_layout¶
The actor parameter layout to use for filtering calendar views.
Default value for a Lino Avanti site:
>>> print(dd.plugins.calview.params_layout) user project event_type courses_course courses_line state