PIM Manager: implement removed+added=modified change merging

At least in one case, folks emitted a removed + changed signal
when a contact was modified in EDS. Therefore implement the
merging of these two different change signals into on at the
D-Bus level.
This commit is contained in:
Patrick Ohly 2012-10-10 14:34:12 +02:00
parent 90ef1f063a
commit 0e6c02b40a
2 changed files with 21 additions and 8 deletions

View file

@ -222,6 +222,13 @@ void FullView::individualsChanged(GeeSet *added,
removed ? gee_collection_get_size(GEE_COLLECTION(removed)) : 0,
message);
typedef GeeCollCXX<FolksIndividual *> Coll;
// Remove first, to match the "remove + added = modified" change optimization
// in Manager::handleChange().
if (removed) {
BOOST_FOREACH (FolksIndividual *individual, Coll(removed)) {
removeIndividual(individual);
}
}
if (added) {
// TODO (?): Optimize adding many new individuals by pre-sorting them,
// then using that information to avoid comparisons in addIndividual().
@ -229,11 +236,6 @@ void FullView::individualsChanged(GeeSet *added,
addIndividual(individual);
}
}
if (removed) {
BOOST_FOREACH (FolksIndividual *individual, Coll(removed)) {
removeIndividual(individual);
}
}
}
void FullView::individualModified(gpointer gobject,

View file

@ -348,9 +348,20 @@ class ViewResource : public Resource, public GDBusCXX::DBusObjectHelper
}
// More complex merging is possible. For example, "removed 1
// at #10" and "added 1 at #10" could be turned into "modified
// 1 at #10". But it is uncertain how common and useful that
// would be, so not implemented...
// at #10" and "added 1 at #10" can be turned into "modified
// 1 at #10". This happens when a contact gets modified and
// folks decides to recreate the FolksIndividual instead of
// modifying it.
if (m_pendingChange.m_call == &m_contactsRemoved &&
&call == &m_contactsAdded &&
start == m_pendingChange.m_start &&
count == m_pendingChange.m_count) {
SE_LOG_DEBUG(NULL, NULL, "handle change %s: removed individuals were re-added => #%d + %d modified",
getPath(),
start, count);
m_pendingChange.m_call = &m_contactsModified;
return;
}
// Cannot merge changes.
flushChanges();