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
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "Dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/dev