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.
This commit is contained in:
parent
d79bc6943f
commit
bdf8d33f44
1 changed files with 38 additions and 31 deletions
|
@ -523,8 +523,8 @@ void FilteredView::refineFilter(const boost::shared_ptr<IndividualFilter> &indiv
|
||||||
++index;
|
++index;
|
||||||
} else {
|
} else {
|
||||||
// No longer matched, remove it.
|
// No longer matched, remove it.
|
||||||
m_removedSignal(index, *data);
|
|
||||||
m_local2parent.erase(m_local2parent.begin() + index);
|
m_local2parent.erase(m_local2parent.begin() + index);
|
||||||
|
m_removedSignal(index, *data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_filter = individualFilter;
|
m_filter = individualFilter;
|
||||||
|
@ -537,7 +537,6 @@ void FilteredView::refineFilter(const boost::shared_ptr<IndividualFilter> &indiv
|
||||||
|
|
||||||
void FilteredView::addIndividual(int parentIndex, const IndividualData &data)
|
void FilteredView::addIndividual(int parentIndex, const IndividualData &data)
|
||||||
{
|
{
|
||||||
if (m_filter->matches(data)) {
|
|
||||||
// We can use binary search to find the insertion point.
|
// We can use binary search to find the insertion point.
|
||||||
// Check last entry first, because that is going to be
|
// Check last entry first, because that is going to be
|
||||||
// very common when adding via doStart().
|
// very common when adding via doStart().
|
||||||
|
@ -551,14 +550,19 @@ void FilteredView::addIndividual(int parentIndex, const IndividualData &data)
|
||||||
m_local2parent.end(),
|
m_local2parent.end(),
|
||||||
parentIndex);
|
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)) {
|
||||||
size_t index = it - m_local2parent.begin();
|
size_t index = it - m_local2parent.begin();
|
||||||
it = m_local2parent.insert(it, parentIndex);
|
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());
|
SE_LOG_DEBUG(NULL, NULL, "filtered view: added at #%ld/%ld", index, m_local2parent.size());
|
||||||
m_addedSignal(index, data);
|
m_addedSignal(index, data);
|
||||||
|
@ -573,19 +577,22 @@ void FilteredView::removeIndividual(int parentIndex, const IndividualData &data)
|
||||||
std::lower_bound(m_local2parent.begin(),
|
std::lower_bound(m_local2parent.begin(),
|
||||||
m_local2parent.end(),
|
m_local2parent.end(),
|
||||||
parentIndex);
|
parentIndex);
|
||||||
if (it != m_local2parent.end() && *it == parentIndex) {
|
// Removing a contact in the parent changes values in our mapping
|
||||||
size_t index = it - m_local2parent.begin();
|
// array, regardless whether the removed contact is part of our
|
||||||
SE_LOG_DEBUG(NULL, NULL, "filtered view: removed at #%ld/%ld", index, m_local2parent.size());
|
// view. Shift all following indices, including the removed entry
|
||||||
it = m_local2parent.erase(it);
|
// if it is part of the view.
|
||||||
m_removedSignal(index, data);
|
bool found = it != m_local2parent.end() && *it == parentIndex;
|
||||||
|
for (Entries_t::iterator it2 = it;
|
||||||
|
it2 != m_local2parent.end();
|
||||||
|
++it2) {
|
||||||
|
(*it2)--;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now reduce the index in our mapping for all following entries.
|
if (found) {
|
||||||
// Not particularly efficient when multiple individuals get
|
size_t index = it - m_local2parent.begin();
|
||||||
// removed.
|
SE_LOG_DEBUG(NULL, NULL, "filtered view: removed at #%ld/%ld", index, m_local2parent.size());
|
||||||
while (it != m_local2parent.end()) {
|
m_local2parent.erase(it);
|
||||||
(*it)--;
|
m_removedSignal(index, data);
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue