-- /ivy/binding/calendar/calendarDoc.tioga
-- documentation and description of Calendar
-- Last edited by: Binding, August 24, 1984 4:22:39 pm PDT
Calendar:
The browser and editor of a personal calendar system
Carl Binding (August 31, 1984)
Filed on: [Ivy]<Binding>Calendar>CalendarDoc.tioga

© Copyright 1984 Xerox Corporation. All rights reserved.
Abstract: This document briefly describes the calendar package. The calendar package is a tool which allows to browse the Hickory data base and edit existing events or enter new events into Hickory. Its functionality is aimed to model a simple personal calendar.
XEROX  Xerox Corporation
   Palo Alto Research Center
    3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
Introduction
Calendar is a tool, implementing a simple personal calendar. It allows to view calendar events stored in the Hickory data base on a day per day, month per month or year per year basis. Furthermore a template oriented editor allows to create new events and enter them into Hickory. Existing events can also be edited via this editor.
Calendar is a Hickory client, similar to Remember. Both tools communicate via Hickory's client notification mechanism. Hence, changes made to the Hickory data base via the Calendar editor are reflected in Remember.
To use Calendar, you must have Hickory running on your machine. Then bringover Calendar ( /Ivy/Binding/Calendar/Calendar.df) into the local directory ///Hickory/Calendar and say "Calendar" to the Commander. This should load and start up the calendar package. If you bringover Calendar into another directory, it won't find the icon files it needs.
External aspects of Calendar
There are two main modes in Calendar. The first is browsing through your personal calendar. The other one is entering a new event respectively editing an already existing event. We shall first discuss the browsing mode. When calendar starts off, you will be shown todays calendar page. How you can see other things is explained below.
Day Browser
Here you see all the events of that day. You see the time and possibly the duration of the event as the first information. A "M" indicates that there is a Walnut message associated with this event. (this can be done with Remember's Remind button in the Walnut viewer). As a next item of information, the text associated with the event is displayed. Finally, you see the place where the event is happening. Note that both, text and place information might be truncated. Since it would be too slow to figure out the precise length of each text string, alignment is not really nice, sorry about that.
At the top of the day viewer, you see a set of buttons. Let's see what they do:
Next: shows the next calendar day
Previous: shows the previous calendar day
Month: will display the month of that day, i.e. if you see August 31, 1984 you will wind up seeing the month of August 1984.
Enter: will enter the editor to edit a new event, i.e. the calendar form you will see is blank.
Print: will print the events of that day. Currently not implemented.
Edit: will enter the editor to edit an existing event, i.e. the calendar form you will see is initialized to the selected event.
Forget: will set the Forgotten attribute of the selected event. Subsequent browsing through your calendar will not display the forgotten event, although it still is stored in Hickory.
ShowMsg: if the event has a Walnut message attached to it, it will be displayed in an appropriate viewer. Walnut must be loaded of course!
To select a singular event to be edited, forgotten etc, left click on it. To undo the selection left click again. Calendar expects you to first select an event and then the action to perform with it.
Month Browser
In this mode, you see all the events of that month. For each day of that month, you see the (truncated) text strings of the events of that day. Each individual day viewer is a scrollable text viewer, so you can see them all by scrolling up and down in the usual way.
At the top of the month viewer, you again see a set of buttons. The semantics of their actions should be obvious. In order to take a closer look at one particular day, you can middle click on the title of that day. This then will bring you back to the day browser, displaying the selected day.
Year Browser
Here you see all the events of that year. Note that building a year browser might take some time, so be patient! Days of that year where one or more events are happening have a grey background.
At the top of the year viewer, you again see a set of buttons. The semantics of their actions should be really obvious by now. In order to take a closer look at one particular month, you must middle click on the title of that month. This then will bring you back to the month browser, displaying the selected month. You cannot jump back directly to a day browser while in the year browser.
The calendar form editor
To enter a new event or simple edit an existing event of Hickory, you can use the template based calendar form. We now briefly describe what things you are able to do within the form.
The menu
The menu of the calendar form has three entries. Here is what they do:
DoIt: This will gather the information as it is currently displayed within the form and attempt to build a set of Hickory events, which are then entered into the data base. In case you are editing an existing event, only the relevant attributes in Hickory are changed.
Erase: This will clear the form of all the text and you end up with a blank form.
Reset: If you are editing an existing event, you can redisplay the unaltered original by using this menu entry. Resetting a new event will blank out the form.
The template
The template allows you to specify a calendar entry. Except the Text and Time field, all the fields are defaulted. At the top of the template you have a set of dates. Left clicking on a year, month or day updates the selected date. Note that if you change the year or month selection, the day grid is updated. Middle clicking on one of the buttons in the year, month or day table will bring you into browsing mode. Most of the other fields of the template are having a text viewer associated with them. To set the input focus you can use the mouse, clicking within the text viewer or left click on the button, which labels the field. This will select the current input (if any) in pending delete mode. The Group and Repetition field also allow for a menu selection. To select, middle click on the item of interest. To undo a selection, a second middle click erases the selected item. Since the Group menu might include more items than you can see at once, you can scroll it left or right. To scroll left, click the left mouse button and to scroll right, use your right mouse button.
Once you have selected the date on which you want to schedule your event, you must fill in the Text and Time fields. The Text field can take arbitrary text. The Time field allows you to schedule events starting on the selected date, stretching over any time period. The syntax of it is as follows:
Times ::= startTime [ '—' endTime ] { ';' startTime [ '—' endTime ] }
startTime ::= Text string parsed by Tempus.Parse
endTime ::= Text string parsed by Tempus.Parse
startTime is interpreted by Tempus.Parse with respect to 0:00 of the selected date and endTime is interpreted with respect to startTime. Hence, if you have selected 8/31/1984 and startTime = noon and endTime = Sunday, you will eventually create a set of Hickory events that cover the period from 8/31/1984 — 9/2/1984 0:00. The interval between startTime and endTime will of course be the duration of the event.
There is one tricky thing to notice here. A single Hickory event cannot stretch out over more than one day. The reason is that it would be too cumbersome for Calendar to analyze and display such muliple day events correctly. Therefore, the form interpreter translates such long events into a set of one day events, which are then individually entered into Hickory. Beware, this might come up as a surprise when you want to edit the event: out of one Calendar event specification there are now several real Hickory events. The same is the case when more than one startTimeendTime is specified. If you give "noon — 14:30; 15:30 — 16:30" as time specification, two distinct events will be entered into Hickory and thus you cannot alter both by editing one of them. Something you have to bear in mind...!
The remaining fields of the template are optional. They all take on their default values, if you do not set their contents. Let's talk about each field in turn, what it means and how to use it.
Protection: an event can either be Private or Public. Although for now Hickory and Calendar don't really work with shared data bases, this might become useful some day. Defaults to Private.
Reminder: an event can be a Reminder, in which case it is "seen" by Remember. Defaults to "yes", i.e. the event will be scheduled by Remember.
Place: this field takes any rope and is of course an indication where the event happens. Defaults to NIL.
Repetition: events can be specified to occur repeatedly. The most common repetition types can be selected from the presented menu. More complicated repetitions can be specified by using the text viewer of the Repetition field in order to specify a time interval, that must be understandable to Tempus.Parse. For instance, you can say "Sunday" and the event will be scheduled every Sunday. It is Hickory that does the computation of the repetition, but a repeated event is in fact one single Hickory event. You have to bear this in mind when you edit a repeated event. It is the base event (i.e. the very first occurrence of it) that you will edit, thereby changing all of the occurrences. Defaults to no repetition. In case you have selected a repetition from the menu and also have specified an interval in the text viewer, the selected menu item overrides the interval specification of the text viewer.
Groups: an event can be a member of zero, one or several groups. You either can select groups out of the menu, by middle clicking them. New groups (i.e. those that are not yet registered with Hickory) are entered via the text viewer. A group is any character string, separated by '; or ',. Hence, "group one; group two" will give you two new groups. Notice that new groups should appear in the menu, once they are entered into Hickory. The default is no group.
RepeatUntil: this field lets you specify until when a repeated event is repeated. A rope, to be interpreted by Tempus.Parse, is the right thing to put here. For example, "September 15, 1984" will repeat the event until 9/15/1984 0:00. The default is BasicTime.latestGMT. (i.e. January, 18, 2036, 19:14:05)
KeepUntil: events are kept within the Hickory data base until this time. Again, you have to supply a rope, which is to be understood by Tempus.Parse. Default here is BasicTime.latestGMT too. Inside Hickory there is a daemon process which throws away the garbage in the middle of every night.
Once you have filled out the form, left click the DoIt menu item. This will interpret the contents of the form and, if everything goes well, enter the event(s) into the database. Hickory then calls back Calendar in order to enable it too reflect the change in its different viewers. Calendar checks for nonsense on your form and signals that with a blinking message in the message window. Unfortunately the error reporting is kind of ad hoc and it also reports only one error at a time! But it should not be too hard to get things right, really!
General organization of the program
You have been reading the above, and roughly know what you can do with Calendar. But oh, surprise, you discover a bug. (There probably are quite a few). If you feel like taking a look into the code, reading this section might help you along.
Calendar uses Hickory as the long term storage for events. However it prefetches events over a rather large time interval when starting up and then uses Hickory's client notification mechanism in order to reflect write changes to the data base correctly.
Calendar is a multiple module monitor. The client interface is currenly only exporting a bunch of types, no operations. Following private interfaces are making up Calendar:
CalStorage: this interface defines the internal storage facilities of Calendar for Hickory events. The global, protected variables are stuffed into a monitored record, protData, that is imported in most other modules and also opened. Hence, if you see a variable and don't find its declaration, CalStorage.protData might be the right place to look.
CalSupport: many of the useful routines throughout Calendar are exported from here.
CalBrowser: exports the operations that enable to browse your personal calendar, ie. the Hickory data base.
CalForm: exports the operation that builds up the calendar event editor form on the screen.
CalEnter: the routine that finishes up translation of a form into a set of Hickory event is exported from here.
CalNuts: exports the routines that register Calendar and its viewers with Nuts.
CalWalnut: exports the routine that allows to take a look at the walnut message of an event.
Implementation of those interfaces is scattered throughout a set of implementation modules. All of which use the monitor lock exported by CalStorage. Some of the more interesting implementation facts are described in the next section.
Implementation of it all
As mentionned, Calendar is a Hickory client. It is from Hickory that Calendar gets the calendar events. Events are cached into the local data structures implemented in CalStorageImpl.mesa. The chosen data structure makes it easy to access events of one particular day. When accessing the data base, we attempt to prefetch things as good as we can. Initially a rather large time interval of events is prefetched into CalStorage. This results in much greater efficiency when browsing through the calendar. On the other side we had to maintain cache consistency, which is not always easy.
Cache consistency within Calendar is maintained upon Hickory's notification that the data base has been written. We then analyze the nature of the change and reflect the change in the cached data structures. Essentially we must update CalStorage's events and also update the viewers in which the new or altered events might be appearing. Since changing an event can not only occur from within Calendar itself, but can be done by any Hickory client, we must traverse the entire cache space in order to throw out the old, invalid event. This is time consuming, but I didn't find a smarter way for now. Once old, invalid events have been eliminated, it is easier to insert new events into the cache, for they have the occurrence date with them! My guess is that there are a couple of optimizations possible when destroying invalidated events with the Calendar cache, but the trickiness of it might be relatively high.
Much of the code within calendar deals with creating viewers. As much as possible I have tried to use symbolic names for dimensions. Unfortunately however, there might still be some hidden numeric constants buried within the code. The mainly used interface is VTables, which might not have been the best choice as far as efficiency is concerned. The layout of the calendar form could also be improved. In general, I felt that creating the graphical layout and feed back was the most tricky thing to get right. Some of the viewer interfaces behave hardly reasonable, so I had to resort to trial and error programming. ( Pfui Teufel)
Once viewers are created, they only are moved out of view when another view is to be presented to the user. Exception being the day viewers, which are recreated every time. This might be another spot for improvements...! Maintaining the created viewers increases the efficiency dramatically, but makes the maintenance in case of updates to Hickory a little more painful.
Most of the code is rather straightforward to understand. All modules should be documenting what they do implement. Therefore I will not describe any further details here, I leave it to the reader.
Conclusions
Calendar as it stands now seems to work to some degree of satisfaction. It is however very likely that a couple of bugs remain throughout the entire Calendar - Hickory - Remember world. Given ths relatively short period of time over which Hickory and Calendar were literally patched together, this comes as not too much of a surprise. As a result of time pressure, some of the code might be very sloppy, grossly inefficient or just akward. My apologies, but it was the best I could do.
Ignoring the quality of the code, there are still many other points one can think of, when thinking of a good calendar system.
Conflicts: Currently conflicts are not detected at all. It would be nice to detect conflicts (claim: this is hard in case of repeated events) and possibly give the user some interaction possibilities to handle the conflicting events. Although currenly one can use the editor to adjust an event, the system should draw the user's attention onto the fact. But getting user interaction right and working smoothly is very tricky, so I didn't consider it....
Multiple person calendar: Hickory as the underlying storage for calendar events is not laid out for shared data bases. Doing this and presenting a nice user interface would be quite a challenge. Interesting aspects to consider is protection and access rights to shared data, consistency throughout multiple clients of the data base, that are caching the shared data etc. I guess there is a rather large amount of work that would be needed here.
Query interface: Calendar now does not allow to specify more than the time extent of a query. Even this is implicit... It would be nice to allow the user to specify a more sophisticated query onto Hickory events. Initially I had that in mind, but with time running out... Again, the hard part seems to be the user interface and the smoothness of integration with the rest of the calendar package.
Hardcopy: It should be no big deal to someone who knows the print interfaces to obtain some simple hardcopy of the calendar. Since CalStorage contains all the relevant information, all that is really needed is to go and translate that into the right calls of the appropriate printing interfaces. I didn't feel like doing this, since discovering new interfaces, with their often tricky behavior, was beyond my physical and psychological forces at the end of this summer....
User interface: The user interface to calendar is a result of a rather ad hoc design. One probably could do better as far as the editor is concerned. In particular it would not hurt to be able to specify some of the attributes that Remember uses.
Reminding of events: Currently Remember does this. I have found the code of Remember to be a mess, and by no ways am I sure if I have done the right things to it in order to integrate it with Hickory and Calendar. Extending Calendar with it's own reminding facility and getting rid of Remember might be the right thing to do here...
Integration with Walnut: the only interaction with Walnut is displaying of the walnut message of an event. In the Tahoe programming environment, the calendar allows to send mail at well specified time points. Maybe this is a gimmick, maybe it's useful...
The above list is rather long. I simply feel that the summer was too short to do it all. One of the main errors ( error 34, not 33) was to start off without a clear design of the end product, i.e. the functionality of Calendar. Instead I started off with Remember, trying to put a data base ( Hickory) behind it and finally write the Calendar on top of it. You might as well call that bottom up and well we all know that is not really the right way....