m_dirLister->setShowingDotFiles(show);
m_dirLister->emitChanges();
if (show) {
- slotCompleted();
+ dispatchPendingItemsToInsert();
}
}
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;
}
if (m_roles == roles) {
return;
}
+
+ const QSet<QByteArray> changedRoles = (roles - m_roles) + (m_roles - roles);
m_roles = roles;
if (count() > 0) {
m_itemData[i]->values = retrieveData(m_itemData.at(i)->item, m_itemData.at(i)->parent);
}
- kWarning() << "TODO: Emitting itemsChanged() with no information what has changed!";
- emit itemsChanged(KItemRangeList() << KItemRange(0, count()), QSet<QByteArray>());
+ emit itemsChanged(KItemRangeList() << KItemRange(0, count()), changedRoles);
}
// Clear the 'values' of all filtered items. They will be re-populated with the
m_urlsToExpand.insert(url);
}
} else {
+ // Note that there might be (indirect) children of the folder which is to be collapsed in
+ // m_pendingItemsToInsert. To prevent that they will be inserted into the model later,
+ // possibly without a parent, which might result in a crash, we insert all pending items
+ // right now. All new items which would be without a parent will then be removed.
+ dispatchPendingItemsToInsert();
+
+ // Check if the index of the collapsed folder has changed. If that is the case, then items
+ // were inserted before the collapsed folder, and its index needs to be updated.
+ if (m_itemData.at(index)->item != item) {
+ index = this->index(item);
+ }
+
m_expandedDirs.remove(targetUrl);
m_dirLister->stop(url);
ItemData* itemData = m_itemData.at(childIndex);
if (itemData->values.value("isExpanded").toBool()) {
const KUrl targetUrl = itemData->item.targetUrl();
+ const KUrl url = itemData->item.url();
m_expandedDirs.remove(targetUrl);
+ m_dirLister->stop(url); // TODO: try to unit-test this, see https://bugs.kde.org/show_bug.cgi?id=332102#c11
expandedChildren.append(targetUrl);
}
++childIndex;
return true;
}
-#include "kfileitemmodel.moc"