Merge remote-tracking branch 'origin/KDE/4.11'

This commit is contained in:
Frank Reininghaus 2013-09-09 21:43:29 +02:00
commit 40a51264d1
3 changed files with 73 additions and 32 deletions

View file

@ -190,33 +190,7 @@ bool KFileItemModel::setData(int index, const QHash<QByteArray, QVariant>& value
m_itemData[index]->item.setUrl(url);
}
emit itemsChanged(KItemRangeList() << KItemRange(index, 1), changedRoles);
// Trigger a resorting if the item's correct position has changed. Note
// that this can happen even if the sort role has not changed at all
// because the file name can be used as a fallback.
if (changedRoles.contains(sortRole()) || changedRoles.contains(roleForType(NameRole))) {
// Compare the changed item with its neighbors to see
// if an expensive resorting is needed at all.
const ItemData* changedItem = m_itemData.at(index);
const ItemData* previousItem = (index == 0) ? 0 : m_itemData.at(index - 1);
const ItemData* nextItem = (index == m_itemData.count() - 1) ? 0 : m_itemData.at(index + 1);
if ((previousItem && lessThan(changedItem, previousItem))
|| (nextItem && lessThan(nextItem, changedItem))) {
m_resortAllItemsTimer->start();
} else if (groupedSorting() && changedRoles.contains(sortRole())) {
// The position is still correct, but the groups might have changed
// if the changed item is either the first or the last item in a
// group.
// In principle, we could try to find out if the item really is the
// first or last one in its group and then update the groups
// (possibly with a delayed timer to make sure that we don't
// re-calculate the groups very often if items are updated one by
// one), but starting m_resortAllItemsTimer is easier.
m_resortAllItemsTimer->start();
}
}
emitItemsChangedAndTriggerResorting(KItemRangeList() << KItemRange(index, 1), changedRoles);
return true;
}
@ -966,11 +940,7 @@ void KFileItemModel::slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&
itemRangeList.append(KItemRange(rangeIndex, rangeCount));
}
emit itemsChanged(itemRangeList, changedRoles);
if (changedRoles.contains(sortRole())) {
m_resortAllItemsTimer->start();
}
emitItemsChangedAndTriggerResorting(itemRangeList, changedRoles);
}
void KFileItemModel::slotClear()
@ -1264,6 +1234,58 @@ void KFileItemModel::removeExpandedItems()
m_expandedDirs.clear();
}
void KFileItemModel::emitItemsChangedAndTriggerResorting(const KItemRangeList& itemRanges, const QSet<QByteArray>& changedRoles)
{
emit itemsChanged(itemRanges, changedRoles);
// Trigger a resorting if necessary. Note that this can happen even if the sort
// role has not changed at all because the file name can be used as a fallback.
if (changedRoles.contains(sortRole()) || changedRoles.contains(roleForType(NameRole))) {
foreach (const KItemRange& range, itemRanges) {
bool needsResorting = false;
const int first = range.index;
const int last = range.index + range.count - 1;
// Resorting the model is necessary if
// (a) The first item in the range is "lessThan" its predecessor,
// (b) the successor of the last item is "lessThan" the last item, or
// (c) the internal order of the items in the range is incorrect.
if (first > 0
&& lessThan(m_itemData.at(first), m_itemData.at(first - 1))) {
needsResorting = true;
} else if (last < count() - 1
&& lessThan(m_itemData.at(last + 1), m_itemData.at(last))) {
needsResorting = true;
} else {
for (int index = first; index < last; ++index) {
if (lessThan(m_itemData.at(index + 1), m_itemData.at(index))) {
needsResorting = true;
break;
}
}
}
if (needsResorting) {
m_resortAllItemsTimer->start();
return;
}
}
}
if (groupedSorting() && changedRoles.contains(sortRole())) {
// The position is still correct, but the groups might have changed
// if the changed item is either the first or the last item in a
// group.
// In principle, we could try to find out if the item really is the
// first or last one in its group and then update the groups
// (possibly with a delayed timer to make sure that we don't
// re-calculate the groups very often if items are updated one by
// one), but starting m_resortAllItemsTimer is easier.
m_resortAllItemsTimer->start();
}
}
void KFileItemModel::resetRoles()
{
for (int i = 0; i < RolesCount; ++i) {

View file

@ -323,6 +323,13 @@ private:
void removeExpandedItems();
/**
* This function is called by setData() and slotRefreshItems(). It emits
* the itemsChanged() signal, checks if the sort order is still correct,
* and starts m_resortAllItemsTimer if that is not the case.
*/
void emitItemsChangedAndTriggerResorting(const KItemRangeList& itemRanges, const QSet<QByteArray>& changedRoles);
/**
* Resets all values from m_requestRole to false.
*/

View file

@ -392,6 +392,18 @@ void KFileItemModelTest::testResortAfterChangingName()
QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsMoved(KItemRange,QList<int>)), DefaultTimeout));
QCOMPARE(itemsInModel(), QStringList() << "b.txt" << "c.txt" << "d.txt");
// We rename d.txt back to a.txt using the dir lister's refreshItems() signal.
const KFileItem fileItemD = m_model->fileItem(2);
KFileItem fileItemA = fileItemD;
KUrl urlA = fileItemA.url();
urlA.setFileName("a.txt");
fileItemA.setUrl(urlA);
m_model->slotRefreshItems(QList<QPair<KFileItem, KFileItem> >() << qMakePair(fileItemD, fileItemA));
QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsMoved(KItemRange,QList<int>)), DefaultTimeout));
QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt");
}
void KFileItemModelTest::testModelConsistencyWhenInsertingItems()