Howdy, chandler-dev@:
So, I'm getting ready to commit the first round of changes for edit/
update in the next day or two. This should cover the domain model
changes for supporting "lastModified", and I’ve hooked up enough of
the UI (e.g., by adding a field or two to the detail view) that you
can tell edit state is being tracked.
Here's a high-level overview. It's perhaps a little long and heavy on
using the code as illustration, but comments or suggestions are
welcome. If you're a managerial type, there are some TODOs at the
end, too.
1. In osaf.pim.items, there's now a Modification enumerated type that
is used to say what the last change to a given ContentItem was:
class Modification(schema.Enumeration):
"""
Enumeration of the types of modification that are part of
the edit/update workflows (a.k.a. "Stamping Storyboards")
"""
values = { "edited":100, "queued":200, "sent":300, "updated":400 }
2. The design requires some state to be associated with each item;
for example, once an invitation has been sent, future sendings are
actually called "updates". So, besides just storing the what the last
modification, there's a set of flags that is used to maintain that
history:
(added to ContentItem):
lastModification = schema.One(
Modification,
doc="What the last modification was"
)
modifiedFlags = schema.Many(
Modification,
initialValue=set([]),
description='Used to track the modification state of the item'
)
3. I added the following method to ContentItem:
def changeEditState(self, modType=Modification.edited, who=None,
when=None):
This does the job of updating the lastModified-related attributes,
including modifiedFlags, as appropriate. (See #7 for how the UI ends
up calling this).
4. There's a "byline" Calculated attribute on ContentItem; this is
used to show a string like "Edited by me on 12/21/2006" in the detail
view.
5. I added an "error" attribute (a schema.Text) that stores a string
containing the last error associated with a given item. At the
moment, it’s only used during mail delivery failures, but in theory
it could be used for sharing problems, too.
6. I changed the mail delivery code to use ContentItem.changeEditState
(); in particular, we set the edited state to queued when we first
hand off your message to the twisted thread for delivery, and set the
sent/updated/error attributes as appropriate when done.
7. Making sure the UI calls changeEditState() when the user makes
changes was an interesting strategy. One option I tried, but seemed a
little haphazard, was to find all the setattr() calls in the various
AttributeEditor subclasses, and add calls to changeEditState(). I
realized this would also lead to weirdness if, for example, you
edited a recurring event, because there the proxy would delay the
actual attribute change till the user had confirmed it, but the
change to lastModified would have happened anyway.
So, for now I went via a different route, which was to retrofit the
occurrence proxy to call changeEditState(), even for items that
aren’t recurring events. There are probably a few cases where we are
explicitly not using the proxy in the UI; it's on my list to seek out
and find those, and deal with the case where we want to call
changeEditState() but not have the recurring event dialog show up.
8. I reworked some of Bryan Stearns' code for the communication
column icons a little. I left the code that figures out what icon to
use in the osaf.views.main.summaryblocks, but I moved the calculation
of the various bits that contribute to an item's "communication
state" over to an Annotation in osaf.pim.mail:
class CommunicationStatus(schema.Annotation):
schema.kindInfo(annotates=items.ContentItem)
# These flag bits govern the sort position of each
communications state:
# UPDATE = 1
# IN = 1
# OUT = 1
# DRAFT = 1
# QUEUED = 1
# SENT = 1
# NEEDS_REPLY = 1
# READ = 1
# ERROR = 1
UPDATE, IN, OUT, DRAFT, QUEUED, SENT, NEEDS_REPLY, READ, ERROR = (
1<<n for n in xrange(9)
)
@staticmethod
def getItemCommState(itemOrUUID, view=None):
"""Given an item or a UUID, determine its communications
status"""
...
attributes = ... # attributes that contribute toward
Communication status
status = schema.Calculated(
schema.Integer,
basedOn=tuple(t[0] for t in attributes),
fget=lambda self: self.getItemCommState(self.itsItem),
doc="A 'bitfield' of (UPDATE, IN, OUT, DRAFT, ...) |'ed
together"
9. The index used by the communication column now uses the above
CommunicationStatus.status attribute (and knows the dependency on
CommunicationStatus.attributes). Howvever, as Bryan originally
designed it, this could be done via a method index and the
getItemCommState method.
10. In the detail view, I added fields to show the byline and error
string (if any), and changed the "from" field to be a "send as" for
outgoing messages. As I'm a domain-model troglodyte lacking in high-
level UI sensibilities, these probably need some tweaking w.r.t
positioning, fonts and all that fun stuff.
TODO:
=====
- Add support for lastModifiedBy. (Currently, this value is always
None, which means it's treated as being by the user). Mainly, I/we
need to decide on using Contact vs EmailAddress here.
- Review the various CommunicationStatus states, to make sure they
match the design spec.
- Look into how all this works (or doesn't!) with recurring events.
- Currently, there's an SMTPDeliveryStatus class in the mail code
that tracks DRAFT/QUEUED/SENT/ERROR state. Look into unifying this
with the enumerated type above, or for moving the communication-
related Modification values into the mail module somehow. If I knew
how to do this cleanly, I probably would have done it already, so
suggestions are welcome :).
- Add support for a 'created' Modification type. Currently, if you
create a new item, it shows up as "Created by me ...". Then, as soon
as you change something, it says "Edited by me ...". As a nice to
have (IIRC), the design called for it remaining "Created" in this
case, until you switch focus to a different item in the detail view.
I had a first cut at doing this, but it turns out it depends on some
changes I’m making in the recurrence branch.
- UI polish/review detail view changes with Reid/Bryan.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
Open Source Applications Foundation "chandler-dev" mailing list
http://lists.osafoundation.org/mailman/listinfo/chandler-dev