20120721 ======== - `on_user_change` and `after_ui_save` are two solutions for the same problem. Can replace `after_ui_save` with `on_user_change`, but `on_user_change` should receive the complete `ar`, not only the web request. --> Replaced `on_user_change` by new method :meth:`lino.core.modeltools.Model.before_ui_save`. And we now call it from :meth:`lino.ui.extjs3.ext_ui.ExtUI.form2obj_and_save` and no longer from :mod:`lino.utils.dblogger` (who is responsible just for logging: e.g. it is also used by :term:`watch_tim` which cannot be considered as a user change). - Bugfix: Calling "Act as..." from the Calendar Panel doesn't work. Caused a "Uncaught TypeError: Object [object Object] has no method 'set_base_param'" in JS console. Calendar workflow ----------------- Event state "suggested" now means that your colleague has fixed a rendez-vous in your name with a client, the client is informed and you must confirm that the date/time suits you. If it doesn't, *you* are responsible for contacting the client and finding a new date/time. Writing end-user documentation ------------------------------ I started a user documentation page for the calendar module: :lino:`/pcsw/calendrier`. But this page obviously is another example of why you should not ask the developer of a framework to write end-user documentation for one of the applications developed using that framework. I got stuck when I had the feeling that now I should add some screenshots, and I wanted them to be in French, of course. Instead of screenshots, Lino has now a series of subtle optimizations and bugfixes which are useful only in multilingual sites: Automatic events and tasks are now generated in the user's language. cal.PanelCalendars now returns calendar descriptions in the user's language. Users now inherit the language of their partner (if they have one). The messages in :xfile:`linolib.js` hadn't been extracted during the last 5 months. Or a funny little problems like with this excerpt from :srcref:`/lino/ui/extjs3/linolib.js`:: config.bbar = config.bbar.concat([ '->', { text: '[$_("Help Text Editor")]', handler: Lino.help_text_editor, qtip: "$_('Edit help texts for fields on this model.')", scope: this} ]) (And the French for "Help Text Editor" is "Editeur textes d'aide". Do you guess why there was a Javascript syntax error after translating?) Another subtile bug was: - Event.summary_row generated the following link which was supposed to open the detail window on that event:: javascript:Lino.cal.Events.detail_action.run({ "record_id": 238 }) That worked for system admins, but normal users don't have `Lino.cal.Events` (seeing all Events at once is reserved to managers). Lino now links to the detail action of MyEvents. :func:`lino_xl.lib.cal.reminders` manually adds a `_detail_action` attribute to each instance which is detected by :meth:`instance_handler `. This solution is not beautiful, but works at least. :meth:`instance_handler ` now also tests whether the user has permission to execute that detail handler. For example the user names in jobs.UsersWithClients are no longer clickable for normal users because only system administrators may see the detail of other users. And this one took me also quite some time: - Buttons "Save" and "Delete" are displayed in German also for French users. It was simply due to the fact that :mod:`lino.core.actions` used `ugettext` and not `ugettext_lazy` as `_`:: # from django.utils.translation import ugettext as _ from django.utils.translation import ugettext_lazy as _ But the most difficult and not yet solved problem is: the Ext.ensible CalendarPanel translates "Calendar" to "Agenda" in French...