diff options
| -rw-r--r-- | src/kitemviews/kfileitemmodel.cpp | 36 | ||||
| -rw-r--r-- | src/kitemviews/kitemrange.h | 10 | ||||
| -rw-r--r-- | src/tests/CMakeLists.txt | 7 | ||||
| -rw-r--r-- | src/tests/kfileitemmodeltest.cpp | 22 | ||||
| -rw-r--r-- | src/tests/kitemrangetest.cpp | 75 |
5 files changed, 148 insertions, 2 deletions
diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index de3c3eb22..b3b926c3a 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -395,7 +395,41 @@ int KFileItemModel::index(const KUrl& url) const index = m_items.value(urlToFind, -1); } - Q_ASSERT(index >= 0 || m_items.count() == m_itemData.count()); + if (index < 0) { + // The item could not be found, even though all items from m_itemData + // should be in m_items now. We print some diagnostic information which + // might help to find the cause of the problem, but only once. This + // prevents that obtaining and printing the debugging information + // wastes CPU cycles and floods the shell or .xsession-errors. + static bool printDebugInfo = true; + + if (m_items.count() != m_itemData.count() && printDebugInfo) { + printDebugInfo = false; + + kWarning() << "The model is in an inconsistent state."; + kWarning() << "m_items.count() ==" << m_items.count(); + kWarning() << "m_itemData.count() ==" << m_itemData.count(); + + // Check if there are multiple items with the same URL. + QMultiHash<KUrl, int> indexesForUrl; + for (int i = 0; i < m_itemData.count(); ++i) { + indexesForUrl.insert(m_itemData.at(i)->item.url(), i); + } + + foreach (const KUrl& url, indexesForUrl.uniqueKeys()) { + if (indexesForUrl.count(url) > 1) { + kWarning() << "Multiple items found with the URL" << url; + foreach (int index, indexesForUrl.values(url)) { + const ItemData* data = m_itemData.at(index); + kWarning() << "index" << index << ":" << data->item; + if (data->parent) { + kWarning() << "parent" << data->parent->item; + } + } + } + } + } + } return index; } diff --git a/src/kitemviews/kitemrange.h b/src/kitemviews/kitemrange.h index 70927b915..ecc03988d 100644 --- a/src/kitemviews/kitemrange.h +++ b/src/kitemviews/kitemrange.h @@ -78,7 +78,10 @@ KItemRangeList KItemRangeList::fromSortedContainer(const Container& container) int index = *it; int count = 1; - ++it; + // Remove duplicates, see https://bugs.kde.org/show_bug.cgi?id=335672 + while (it != end && *it == index) { + ++it; + } while (it != end) { if (*it == index + count) { @@ -89,6 +92,11 @@ KItemRangeList KItemRangeList::fromSortedContainer(const Container& container) count = 1; } ++it; + + // Remove duplicates, see https://bugs.kde.org/show_bug.cgi?id=335672 + while (it != end && *it == *(it - 1)) { + ++it; + } } result << KItemRange(index, count); diff --git a/src/tests/CMakeLists.txt b/src/tests/CMakeLists.txt index 4ba68dd73..c1f4124ff 100644 --- a/src/tests/CMakeLists.txt +++ b/src/tests/CMakeLists.txt @@ -12,6 +12,13 @@ set(kitemsettest_SRCS kde4_add_unit_test(kitemsettest TEST ${kitemsettest_SRCS}) target_link_libraries(kitemsettest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) +# KItemRangeTest +set(kitemrangetest_SRCS + kitemrangetest.cpp +) +kde4_add_unit_test(kitemrangetest TEST ${kitemrangetest_SRCS}) +target_link_libraries(kitemrangetest dolphinprivate ${KDE4_KIO_LIBS} ${QT_QTTEST_LIBRARY}) + # KItemListSelectionManagerTest set(kitemlistselectionmanagertest_SRCS kitemlistselectionmanagertest.cpp diff --git a/src/tests/kfileitemmodeltest.cpp b/src/tests/kfileitemmodeltest.cpp index 48e72e83f..c584c5e62 100644 --- a/src/tests/kfileitemmodeltest.cpp +++ b/src/tests/kfileitemmodeltest.cpp @@ -95,6 +95,7 @@ private slots: void testRefreshFilteredItems(); void testCollapseFolderWhileLoading(); void testCreateMimeData(); + void testDeleteFileMoreThanOnce(); private: QStringList itemsInModel() const; @@ -1697,6 +1698,27 @@ void KFileItemModelTest::testCollapseFolderWhileLoading() QVERIFY(!m_model->isExpanded(1)); } +void KFileItemModelTest::testDeleteFileMoreThanOnce() +{ + QStringList files; + files << "a.txt" << "b.txt" << "c.txt" << "d.txt"; + m_testDir->createFiles(files); + + m_model->loadDirectory(m_testDir->url()); + QVERIFY(QTest::kWaitForSignal(m_model, SIGNAL(itemsInserted(KItemRangeList)), DefaultTimeout)); + QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "b.txt" << "c.txt" << "d.txt"); + + const KFileItem fileItemB = m_model->fileItem(1); + + // Tell the model that a list of items has been deleted, where "b.txt" appears twice in the list. + KFileItemList list; + list << fileItemB << fileItemB; + m_model->slotItemsDeleted(list); + + QVERIFY(m_model->isConsistent()); + QCOMPARE(itemsInModel(), QStringList() << "a.txt" << "c.txt" << "d.txt"); +} + QStringList KFileItemModelTest::itemsInModel() const { QStringList items; diff --git a/src/tests/kitemrangetest.cpp b/src/tests/kitemrangetest.cpp new file mode 100644 index 000000000..9f3f79980 --- /dev/null +++ b/src/tests/kitemrangetest.cpp @@ -0,0 +1,75 @@ +/*************************************************************************** + * Copyright (C) 2014 by Frank Reininghaus <[email protected]> * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * + ***************************************************************************/ + +#include <qtest_kde.h> + +#include "kitemviews/kitemrange.h" + +#include <QVector> + +Q_DECLARE_METATYPE(QVector<int>); +Q_DECLARE_METATYPE(KItemRangeList); + +class KItemRangeTest : public QObject +{ + Q_OBJECT + +private slots: + void testFromSortedContainer_data(); + void testFromSortedContainer(); +}; + +void KItemRangeTest::testFromSortedContainer_data() +{ + QTest::addColumn<QVector<int> >("sortedNumbers"); + QTest::addColumn<KItemRangeList>("expected"); + + QTest::newRow("empty") << QVector<int>() << KItemRangeList(); + QTest::newRow("[1]") << (QVector<int>() << 1) << (KItemRangeList() << KItemRange(1, 1)); + QTest::newRow("[9]") << (QVector<int>() << 9) << (KItemRangeList() << KItemRange(9, 1)); + QTest::newRow("[1-2]") << (QVector<int>() << 1 << 2) << (KItemRangeList() << KItemRange(1, 2)); + QTest::newRow("[1-3]") << (QVector<int>() << 1 << 2 << 3) << (KItemRangeList() << KItemRange(1, 3)); + QTest::newRow("[1] [4]") << (QVector<int>() << 1 << 4) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(4, 1)); + QTest::newRow("[1-3] [5]") << (QVector<int>() << 1 << 2 << 3 << 5) << (KItemRangeList() << KItemRange(1, 3) << KItemRange(5, 1)); + QTest::newRow("[1] [5-6]") << (QVector<int>() << 1 << 5 << 6) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 2)); + QTest::newRow("duplicates: 1 1") << (QVector<int>() << 1 << 1) << (KItemRangeList() << KItemRange(1, 1)); + QTest::newRow("duplicates: 1 1 1") << (QVector<int>() << 1 << 1 << 1) << (KItemRangeList() << KItemRange(1, 1)); + QTest::newRow("duplicates: 1 1 5") << (QVector<int>() << 1 << 1 << 5) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 1)); + QTest::newRow("duplicates: 1 5 5") << (QVector<int>() << 1 << 5 << 5) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 1)); + QTest::newRow("duplicates: 1 1 1 5") << (QVector<int>() << 1 << 1 << 1 << 5) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 1)); + QTest::newRow("duplicates: 1 5 5 5") << (QVector<int>() << 1 << 5 << 5 << 5) << (KItemRangeList() << KItemRange(1, 1) << KItemRange(5, 1)); + QTest::newRow("duplicates: 1 1 2") << (QVector<int>() << 1 << 1 << 2) << (KItemRangeList() << KItemRange(1, 2)); + QTest::newRow("duplicates: 1 2 2") << (QVector<int>() << 1 << 2 << 2) << (KItemRangeList() << KItemRange(1, 2)); + QTest::newRow("duplicates: 1 1 2 3") << (QVector<int>() << 1 << 1 << 2 << 3) << (KItemRangeList() << KItemRange(1, 3)); + QTest::newRow("duplicates: 1 2 2 3") << (QVector<int>() << 1 << 2 << 2 << 3) << (KItemRangeList() << KItemRange(1, 3)); + QTest::newRow("duplicates: 1 2 3 3") << (QVector<int>() << 1 << 2 << 3 << 3) << (KItemRangeList() << KItemRange(1, 3)); +} + +void KItemRangeTest::testFromSortedContainer() +{ + QFETCH(QVector<int>, sortedNumbers); + QFETCH(KItemRangeList, expected); + + const KItemRangeList result = KItemRangeList::fromSortedContainer(sortedNumbers); + QCOMPARE(expected, result); +} + +QTEST_KDEMAIN(KItemRangeTest, NoGUI) + +#include "kitemrangetest.moc" |
