The owner of an Event or a Task

Users can now see who’s the owner of an automatic calendar Event or Task, and they can jump to that owner by simply clicking on it.

Automatic Calendar components are “owned” (or “governed” or “controlled” by the object) which caused their creation: If the owner gets modified, it may decide to delete or modify all its automatic tasks or events. That’s why some fields are read-only on an automatic task.

For Lino, a calendar component is automatic when its owner field is non-empty.

The owner field is a GenericForeignKey, defined in lino.mixins.Owned.

And GFK fields weren’t well rendered yet.

Now they are rendered as a read-only clickable text that will bring the user to the owner.


The verbose_name of a GFK

One problem remained in the above changes: there was no way to specify a label (or verbose_name) for the GFK itself (that is, the combination of both fields). Here is the relevant code from lino.mixins.Owned:

from django.contrib.contenttypes import generic

class Owned(models.Model):

    owner_type = models.ForeignKey(ContentType,editable=True,
        verbose_name=_('Owner type'))
    owner_id = fields.GenericForeignKeyIdField(owner_type,
    owner = generic.GenericForeignKey('owner_type', 'owner_id')

It was not possible to specify a verbose_name`for field `owner. The author of django.contrib.contenttypes obviously didn’t imagine that somebody might want to do that.

That’s why we now have lino.fields.GenericForeignKey which is a thin extension to Django’s GenericForeignKey.

The new code is:

owner = fields.GenericForeignKey(
  'owner_type', 'owner_id', verbose_name=_("Owned by"))

Started Calendar Panel

I did the first steps for having a “Calendar Panel” command that will use Ext.ensible.cal.CalendarPanel from Extensible.

More concretely: there’s now a new command My menu ‣ Calendar ‣ Calendar Panel which displays a calendar. New lino.Lino.use_extensible to make this feature optional. The calendar is currently still empty. I need to configure eventStore (probably the last challenge for this new feature).