[Kde-pim] Something for the weekend?
Stephen Kelly
steveire at gmail.com
Fri Jan 8 21:24:01 GMT 2010
This is a long email, but not very important to read. It's more of an
archive of ideas.
After discussion,
Conceptually, the information about how messages should be threaded or
parented must come from either parents having a listing of their children,
or children having a reference to their parent. Additional complications
detailed below mean that each item must be aware of either the entire tree,
or hold references to all its ancestors. We're going to go with the knowing
all ancestors option.
The long version:
Evaluating in the parent > child direction would be beneficial from the
point of view of the proxy model because it would mean that mappings to the
source model could be created lazily. That's always preferable, and is the
behaviour of QSFPM and KSelectionProxyModel (on my local machine at least so
far :)) because it reduces the amount of QPersistentModelIndexes which must
be created. Doing it that way would mean the isDescendantOf method would
need to be replaced with a
/**
Reimplement this to return the index in the source model vertically
below @p index. @index is also in the source model.
For example, if the source is a list, and the desired structure is
@code
- 1
- - 2
- - - 3
- - 4
- - 5
- 6
@endcode
Then nextSibling would look something like:
@code
{
if (index == 1) return 6;
// Return invalid if no next sibling.
if (index == 6) return QModelIndex();
// The proxy figures out that some items are missing,
// so knows that hasChildren(1) == true; Further mappings aren't created
// until requested, for example, when the user click expands the tree.
if (index == 2) return 4;
if (index == 4) return 5;
if (index == 5) return QModelIndex();
if (index == 3) return QModelIndex();
}
@endcode
*/
virtual QModelIndex nextSibling(const QModelIndex &index) = 0;
However, the problem with evaluating in the parent > child direction is that
if a child is missing, a grandchild should be a child of the grandparent.
For example,
(Akonadi::Id 7) Alice emails Bob,
-> (Akonadi::Id 56) Bob replies,
-> -> (Akonadi::Id 87) Alice replies to Bob.
If there is one true item hierarchy (and there should be), an Akonadi
attribute would hold a list of children of size 1: (56,) for 7 (87,) for 56.
If there is a search folder for Alices emails, the list of items would look
like:
ItemId: 7, Children: (56,)
ItemId: 87: Children ()
There is no way of knowing that 87 is supposed to be a child of 7 in the
threaded view, because that information is in the not-present item 56. There
is no way to know that 87 should in fact be a child of 7 without 7 holding
information about its entire sub tree. That would mean a lot of duplication
in each item and would obviously be a bad idea.
Storing parent items is then the better idea. There is still a requirement
to store the entire ancestor hierarchy in the Item attribute in case
something is filtered out. The above spiel is just there for completeness
and because it is a better way to implement this from a proxy model point of
view, even if it's not right for Akonadi.
In our Akonadi case it makes more sense to use a isDescendantOf method. This
has the disadvantage that it means all items in the source model must be
accessed and mapped at proxy model creation time, which means that all items
in all proxy models in the chain and the root source model must be accessed
and have mappings created for them, but as the selection proxy model is the
limiter for what items in the etm need to be accessed, it shouldn't be too
much.
In this case, the three emails would have attributes like:
ItemId 7: Parent chain: ()
ItemId 56: Parent chain: (7,)
ItemId 87: Parent chain: (56, 7)
This means that even if 56 is filtered out, 87 still has information that it
should be a descendant of 7. The isDescendantOf method should then be
trivial to write too.
The case of items having multiple parents is also handled in this scenario.
If the message threading agent determines that an item has multiple possible
parents, they would simply all be put in the list, in an arbitrary or
specific order.
For example, if 56 could have parents 34, 67, 45, and grandparents could be
78, 46, 98, 23, 25, 12 (if each of the possible parents itself has two
possible parents).
Then the attribute would contain (34, 67, 45, 78, 46, 98, 23, 25, 12).
Apparently an email having multiple possible parents should be relatively
rare, so we can optimize for the common case. There doesn't seem to be any
other solution anyway.
Similarly, tasks with common subtasks should be possible to handle too. In
the case of sub tasks in the last email, we could have something like this
in two different views in different applications or plasmoids:
- 1
- - 2
- - 3
- 4
- - 2
- - 5
Here, 2 would have an attribute identifying two possible parents, 4, and 1,
so they would appear in the right place even if one model showed the same
subtask twice (in different tasks) as long as no task was a descendant task
of itself.
As suggested earlier at Osnabruck, if we get a lot of use cases of items
with multiple parents, we can just rename it The Great Exploding Ancestor
Tree Model and be done with it.
All the best,
Steve.
_______________________________________________
KDE PIM mailing list kde-pim at kde.org
https://mail.kde.org/mailman/listinfo/kde-pim
KDE PIM home page at http://pim.kde.org/
More information about the kde-pim
mailing list