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

Reply via email to