summaryrefslogtreecommitdiff
path: root/src/dbus/server/pim/folks.cpp
diff options
context:
space:
mode:
authorPatrick Ohly <patrick.ohly@intel.com>2012-11-27 19:36:34 +0100
committerPatrick Ohly <patrick.ohly@intel.com>2012-12-03 17:14:48 +0100
commitbdf8d33f44b47db19a66f59207a8cf29b6d3ebc4 (patch)
tree19a5c2922bf78e251bf2652758d2bb1cf93f2896 /src/dbus/server/pim/folks.cpp
parentd79bc6943f128fc5f58c8b7b5974f6cef68add48 (diff)
Folks: fix change emission in FilteredView + removal of contacts
Fix the order of changes to internal data structures and emitting change signals so that the changes are completed first. That way, if the change signals are hooked up to classes which call the view back, those calls can be processed correctly. The code for removing a contact did this incorrectly: it skipped updating the indices when the removed contact wasn't included in the filtered view, although indices in the parent changed.
Diffstat (limited to 'src/dbus/server/pim/folks.cpp')
-rw-r--r--src/dbus/server/pim/folks.cpp67
1 files changed, 37 insertions, 30 deletions
diff --git a/src/dbus/server/pim/folks.cpp b/src/dbus/server/pim/folks.cpp
index 395f100f..8a20a2da 100644
--- a/src/dbus/server/pim/folks.cpp
+++ b/src/dbus/server/pim/folks.cpp
@@ -523,8 +523,8 @@ void FilteredView::refineFilter(const boost::shared_ptr<IndividualFilter> &indiv
++index;
} else {
// No longer matched, remove it.
- m_removedSignal(index, *data);
m_local2parent.erase(m_local2parent.begin() + index);
+ m_removedSignal(index, *data);
}
}
m_filter = individualFilter;
@@ -537,28 +537,32 @@ void FilteredView::refineFilter(const boost::shared_ptr<IndividualFilter> &indiv
void FilteredView::addIndividual(int parentIndex, const IndividualData &data)
{
+ // We can use binary search to find the insertion point.
+ // Check last entry first, because that is going to be
+ // very common when adding via doStart().
+ Entries_t::iterator it;
+ if (!m_local2parent.empty() &&
+ m_local2parent.back() < parentIndex) {
+ it = m_local2parent.end();
+ } else {
+ it =
+ std::lower_bound(m_local2parent.begin(),
+ m_local2parent.end(),
+ parentIndex);
+ }
+
+ // Adding a contact in the parent changes values in our
+ // mapping array, regardless whether the new contact also
+ // gets and entry in it. Shift all following indices.
+ for (Entries_t::iterator it2 = it;
+ it2 != m_local2parent.end();
+ ++it2) {
+ (*it2)++;
+ }
+
if (m_filter->matches(data)) {
- // We can use binary search to find the insertion point.
- // Check last entry first, because that is going to be
- // very common when adding via doStart().
- Entries_t::iterator it;
- if (!m_local2parent.empty() &&
- m_local2parent.back() < parentIndex) {
- it = m_local2parent.end();
- } else {
- it =
- std::lower_bound(m_local2parent.begin(),
- m_local2parent.end(),
- parentIndex);
- }
size_t index = it - m_local2parent.begin();
it = m_local2parent.insert(it, parentIndex);
- ++it;
- // Shift all following indices.
- while (it != m_local2parent.end()) {
- (*it)++;
- ++it;
- }
SE_LOG_DEBUG(NULL, NULL, "filtered view: added at #%ld/%ld", index, m_local2parent.size());
m_addedSignal(index, data);
@@ -573,20 +577,23 @@ void FilteredView::removeIndividual(int parentIndex, const IndividualData &data)
std::lower_bound(m_local2parent.begin(),
m_local2parent.end(),
parentIndex);
- if (it != m_local2parent.end() && *it == parentIndex) {
+ // Removing a contact in the parent changes values in our mapping
+ // array, regardless whether the removed contact is part of our
+ // view. Shift all following indices, including the removed entry
+ // if it is part of the view.
+ bool found = it != m_local2parent.end() && *it == parentIndex;
+ for (Entries_t::iterator it2 = it;
+ it2 != m_local2parent.end();
+ ++it2) {
+ (*it2)--;
+ }
+
+ if (found) {
size_t index = it - m_local2parent.begin();
SE_LOG_DEBUG(NULL, NULL, "filtered view: removed at #%ld/%ld", index, m_local2parent.size());
- it = m_local2parent.erase(it);
+ m_local2parent.erase(it);
m_removedSignal(index, data);
}
-
- // Now reduce the index in our mapping for all following entries.
- // Not particularly efficient when multiple individuals get
- // removed.
- while (it != m_local2parent.end()) {
- (*it)--;
- ++it;
- }
}
void FilteredView::modifyIndividual(int parentIndex, const IndividualData &data)