[Dev] Detail view and recurrence issues

Bryan Stearns stearns at osafoundation.org
Thu May 26 13:06:02 PDT 2005


Hi Jeffrey,

Without having read your new spec in detail, here are the recurrence 
issues I'm concerned about from the detail view's perspective. (Others 
might want to read the CPIA/AttributeEditor explanation for background 
even if recurrence isn't your thing.)

The detail view gets told to display an item. Based on the kind(s) of 
that item, it includes various combinations of blocks in its presentation.

First issue, the small one: I see that you're using multiple kinds for 
the different kinds of events, but I didn't see whether they have a 
common ancestor, so how the DV builds the view might be an issue: 
basically, it has a mapping of kinds to subtrees of blocks; when 
building the view for an item, it asks "item.isKindOf(kind)" for each 
kind in its mapping, and includes that mapping's subtree if so. The 
calendar block subtree which are currently tagged with CalendarMixinKind 
- if that's not the parent of all the calendar event types, we'll need 
to deal with that.

OK, so we've got a detail view for the selected item. In that detail 
view are a bunch of CPIA blocks, many of which are AEBlocks, which have 
Attribute Editors. This'd be a good spot for an AttributeEditor lesson, 
but first, a CPIA lesson (skip the stuff you already know):

CPIA presents the UI in terms of a hierarchy of Blocks, each of which 
(nearly always) corresponds to a wx widget (which it usually builds 
itself, during an operation we call "rendering"). As you'd expect, many 
of the blocks in the hiearchy are simply containers for other blocks 
that affect layout, implement behavior, or both - some aren't 
containers, but correspond to specific control widgets like checkboxes 
and popup menus; these can also implement behavior in their python code.

This brings us to Attribute Editors, which are python classes (not 
subclasses of Item, so they're not persistant - they're also not Blocks, 
but more on that in a moment) that just know how (given an item, the 
name of an attribute, and optionally a little presentational sugar) to 
produce a widget suitable for editing that item. The Attribute Editor 
also manages flow of data between that widget and the item attribute. 
These Attribute Editors originally came about because the Grid mechanism 
(which we use for summary tables) wants to be able to say "give me an 
editor for this table cell" and get a widget back; though it's made the 
AttributeEditor API pretty crufty supporting both usage models, we now 
also use them in the detail view (and may someday have a dialog-box 
mechanism that uses them).

So we've got Attribute Editors, and we've got CPIA Blocks for our UI - 
what ties them together? AEBlock, a Block subclass that uses the 
Attribute Editor picking mechanism to instantiate an Attribute Editor 
subclass appropriate for the attribute the AEBlock is configured to 
present. So, at "render" time, AEBlock delegates creation of its widget 
to the Attribute Editor; as above, the AE takes care of the data flow 
between the widget and the attribute in the item.

Let's talk about that data flow for a moment. Here's the editing life 
cycle (a little bit simplified, but the major points are right):

- DetailView gets an event that selects an item. Detail View builds a 
tree of blocks based on the item's Kind(s).

- Let's say the item has an attribute named "about", and somewhere in 
the tree of blocks is an AEBlock configured for the "about" attribute.

- At "render" time, that AEBlock asks the item's schema for the type of 
the "about" attribute - it's String - so the AEBlock asks the Attribute 
Editor mechanism for one suitable for Strings. Not surprisingly, it gets 
a new instance of a StringAttributeEditor. The StringAttributeEditor 
instance gets asked by our AEBlock for a widget, and it returns a 
wx.TextCtrl. AEBlock tells the StringAttributeEditor to load the 
attribute's value into the new widget, then the widget gets put into the 
widget hierarchy as part of the normal "render".

- Eventually, the user clicks on the textctrl, and makes a change to its 
value. The StringAttributeEditor knows that the user has changed the 
value, but doesn't write it back to the item.attribute until the focus 
leaves the textctrl or the user hits "enter". This is already an issue 
for us, in terms of validation: some fields are restricted in form, like 
an event's start time: we validate at this write-back time, and if the 
string is invalid, we insert a question mark as user feedback and put it 
back in the textbox without changing the item.attribute. In this 
situation, if the user doesn't go back and fix the problem, that change 
will be discarded; this is an issue for us in that it's possible for 
this to happen without the user seeing it, if the focus is changing 
because the user has selected a different item, is quitting, etc.

This is the big issue: Imagine that the selected item is an instance of 
a recurring event. The thing I haven't been able to figure out is: Where 
is the point of control where something says "hey, this is a recurring 
event! I'd better put up the change-one/change-all/change-all-future box 
and ask the user!"? And then what happens?

... Bryan



More information about the Dev mailing list