[Chandler-dev] Re: annotating selection
John Anderson
john at osafoundation.org
Thu Mar 30 18:32:05 PST 2006
Alec Flett wrote:
> I've been thinking a lot lately about collections. I'd like to take
> some time to discuss IndexedSelectionCollection and its role in
> chandler...
>
> To bring everyone up to speed, I'll summarize how
> IndexedSelectionCollection works, what it buys us, and the problems I
> see with it. I've specifically sent this message to John, Andi, and
> pje because I'd like to brainstorm some ideas and they are the folks
> that will have the best handle on the issues.... but anyone else is
> welcome to offer up ideas as well.
>
> (John, I do realize that the actual ISCollection is more general than
> what I'm about to describe, but I'm trying to discuss the specific use
> case that it was designed for..)
>
> IndexedSelectionCollection works by 'wrapping' or referencing a
> 'source' collection. This source collection is usually a
> SmartCollection stored in the sidebar. When a collection is clicked in
> the sidebar, it is 'wrapped' with an IndexedSelectionCollection that
> is specific for that particular combination of (collection, kind
> filter).. so that if I have a collection 'School' and I click on the
> 'Mail' button in the toolbar, I get a new IndexedSelectionCollection
> (and a FilteredCollection, but that's beyond the scope of what I'm
> trying to get at) just for that, and that ISCollection is what is
> passed to the Table. The table and calendar use this ISCollection
> exclusively to persistently store its collection and current sort (by
> storing the index name as an attribute on the ISCollection instance)
> However, they need to go back to the original collection in order to
> get other metainformation such as color.
>
> So what is IndexedSelectionCollection doing for us?
> 1) provides a "view"-side way of representing and persisting selection
> of items in the source collection - i.e. each instance of a table
> widget can have its own selection by having its own instance of an
> ISCollection which points back to the original source collection.
> Selection is automatically updated as the collection changes due to
> the RangeSet work that Andi and John did.
> 2) provides a container to store indexes for the items in the source
> collection. Rather than storing indexes on the original collection, it
> is storing indexes in the ISCollection. The RangeSet stuff is
> intricately tied to the indexes stored on the collection.
> 3) provides persistent storage of the 'current sort'
>
> I would argue that 2) and 3) aren't really valuable and here's why:
> 2) Indexes on a collection should be on the original collection, not
> on some derivative collection. This allows any consumer of that
> collection to leverage the indexes without going and tracking down an
> IndexedSelectionCollection that references it. For instance, if a
> collection has a 'date' index, then that date index should be
> available to as many views as want it, rather than requiring each
> IndexedSelectionCollection to keep its own 'date' index.
We originally considered doing this and it can be done. However, two
different users may want to have a sort named "date" that works
differently, e.g. one date sorts using one locale and another sorts by
another locale. So as long we build in a mechanism to resolve how
different names map to the same or different sorts it's fine. We choose
the current mechanism because it was easier than implementing such a
mechanism.
>
> 3) I think the 'current sort' is really owned by the CPIA Block or
> Widget referencing the collection, not some intermediate collection.
> The Block/Widget should be persisting the name of the index being used
> for sorting, and be accessing the collection using that index..
Storing the selection on the block leads to the following problem:
Consider the case where you want a single block that is used to view
many different contents (I think the calendar currently works this way).
If you store the selection on the block then your selection becomes
incorrect when you switch to a new contents. Storing the selection with
the contents allows you to restore the collection. Personally, I think
the selection is more closely tied to the index of the collection that
makes up the contents, rather than the Block.
> so to access element x, we currently write
> item = self.contents[x]
> ...and expect that self.contents knows which index to use (as
> determined by self.contents.indexName)
>
> What if instead we wrote:
> item = self.contents.getByIndex(self.currentIndex, x)
>
> Now we don't need an intermediary collection just to hold the current
> index name.
>
> The tricky case is 1). How do we keep selection off the main
> collection and yet have it update automatically when items are
> added/removed from the collection? I thought first about Annotations.
> We still haven't solved the problem of how to maintain selection when
> changing the current index, so perhaps instead we could think about
> the selection as a sort of Annotated dictionary-style attribute, keyed
> off of some part of the block. Basically you'd be hanging a bunch of
> selections off of the collection,
It's not difficult to maintain the selection when switching the index --
it's a task on my list that I haven't finished doing.
>
> So if we had an annotation called SelectionCollection, the block could
> say:
>
> selection =
> SelectionCollection(self.contents).getSelection(self.blockName)
>
> [I'm using blockName as an example, we'd probably want something more
> unique]
> The only trick is getting all the selections to stay current. I
> realized this could be accomplished if every selection was just a
> well-known index on a collection.
>
> Then SelectionCollection wouldn't need to even be an Annotation, even
> though that is the effect:
>
> class SelectionCollection(object):
> def __init__(self, collection):
> self.collection = collection
>
> def getSelectionRanges(self, selectionKey):
> indexName = 'selection_' + selectionKey
> if not self.collection.hasIndex(indexName):
> self.collection.addIndex(indexName, 'numeric')
> return self.collection.getIndex(indexName).getRanges()
>
> Thoughts?
>
> Alec
More information about the chandler-dev
mailing list