X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/b27aefa798267bd8e1b031c66b458196eded19a0..b2cb38214ec403dfc68e5231e0006fe59833515a:/src/kitemviews/kfileitemmodel.cpp diff --git a/src/kitemviews/kfileitemmodel.cpp b/src/kitemviews/kfileitemmodel.cpp index ed45e6975..baf168ddf 100644 --- a/src/kitemviews/kfileitemmodel.cpp +++ b/src/kitemviews/kfileitemmodel.cpp @@ -28,7 +28,7 @@ #include #include -#define KFILEITEMMODEL_DEBUG +// #define KFILEITEMMODEL_DEBUG KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) : KItemModelBase("name", parent), @@ -358,8 +358,8 @@ void KFileItemModel::setRoles(const QSet& roles) m_roles = roles; if (count() > 0) { - const bool supportedExpanding = m_requestRole[IsExpandedRole] && m_requestRole[ExpansionLevelRole]; - const bool willSupportExpanding = roles.contains("isExpanded") && roles.contains("expansionLevel"); + const bool supportedExpanding = m_requestRole[ExpansionLevelRole]; + const bool willSupportExpanding = roles.contains("expansionLevel"); if (supportedExpanding && !willSupportExpanding) { // No expanding is supported anymore. Take care to delete all items that have an expansion level // that is not 0 (and hence are part of an expanded item). @@ -394,7 +394,7 @@ QSet KFileItemModel::roles() const bool KFileItemModel::setExpanded(int index, bool expanded) { - if (isExpanded(index) == expanded || index < 0 || index >= count()) { + if (!isExpandable(index) || isExpanded(index) == expanded) { return false; } @@ -445,7 +445,7 @@ bool KFileItemModel::isExpanded(int index) const bool KFileItemModel::isExpandable(int index) const { if (index >= 0 && index < count()) { - return m_itemData.at(index)->item.isDir(); + return m_itemData.at(index)->values.value("isExpandable").toBool(); } return false; } @@ -462,7 +462,6 @@ void KFileItemModel::restoreExpandedUrls(const QSet& urls) void KFileItemModel::setExpanded(const QSet& urls) { - const KDirLister* dirLister = m_dirLister.data(); if (!dirLister) { return; @@ -674,19 +673,35 @@ void KFileItemModel::slotCanceled() void KFileItemModel::slotNewItems(const KFileItemList& items) { + Q_ASSERT(!items.isEmpty()); + if (m_requestRole[ExpansionLevelRole] && m_rootExpansionLevel >= 0) { - // If the expanding of items is enabled in the model, it might be - // possible that the call dirLister->openUrl(url, KDirLister::Keep) in - // KFileItemModel::setExpanded() results in emitting of the same items - // twice due to the Keep-parameter. This case happens if an item gets - // expanded, collapsed and expanded again before the items could be loaded - // for the first expansion. - foreach (const KFileItem& item, items) { - const int index = m_items.value(item.url(), -1); - if (index >= 0) { - // The items are already part of the model. - return; - } + // To be able to compare whether the new items may be inserted as children + // of a parent item the pending items must be added to the model first. + dispatchPendingItemsToInsert(); + + KFileItem item = items.first(); + + // If the expanding of items is enabled, the call + // dirLister->openUrl(url, KDirLister::Keep) in KFileItemModel::setExpanded() + // might result in emitting the same items twice due to the Keep-parameter. + // This case happens if an item gets expanded, collapsed and expanded again + // before the items could be loaded for the first expansion. + const int index = m_items.value(item.url(), -1); + if (index >= 0) { + // The items are already part of the model. + return; + } + + // KDirLister keeps the children of items that got expanded once even if + // they got collapsed again with KFileItemModel::setExpanded(false). So it must be + // checked whether the parent for new items is still expanded. + KUrl parentUrl = item.url().upUrl(); + parentUrl.adjustPath(KUrl::RemoveTrailingSlash); + const int parentIndex = m_items.value(parentUrl, -1); + if (parentIndex >= 0 && !m_itemData[parentIndex]->values.value("isExpanded").toBool()) { + // The parent is not expanded. + return; } } @@ -719,13 +734,21 @@ void KFileItemModel::slotItemsDeleted(const KFileItemList& items) { dispatchPendingItemsToInsert(); - if (!m_filteredItems.isEmpty()) { + KFileItemList itemsToRemove = items; + if (m_requestRole[ExpansionLevelRole] && m_rootExpansionLevel >= 0) { + // Assure that removing a parent item also results in removing all children foreach (const KFileItem& item, items) { + itemsToRemove.append(childItems(item)); + } + } + + if (!m_filteredItems.isEmpty()) { + foreach (const KFileItem& item, itemsToRemove) { m_filteredItems.remove(item); } } - removeItems(items); + removeItems(itemsToRemove); } void KFileItemModel::slotRefreshItems(const QList >& items) @@ -1073,6 +1096,7 @@ KFileItemModel::Role KFileItemModel::roleIndex(const QByteArray& role) const rolesHash.insert("rating", RatingRole); rolesHash.insert("isDir", IsDirRole); rolesHash.insert("isExpanded", IsExpandedRole); + rolesHash.insert("isExpandable", IsExpandableRole); rolesHash.insert("expansionLevel", ExpansionLevelRole); } return rolesHash.value(role, NoRole); @@ -1133,19 +1157,31 @@ QHash KFileItemModel::retrieveData(const KFileItem& item) } if (m_requestRole[PathRole]) { - data.insert("path", item.localPath()); + if (item.url().protocol() == QLatin1String("trash")) { + const KIO::UDSEntry udsEntry = item.entry(); + data.insert("path", udsEntry.stringValue(KIO::UDSEntry::UDS_EXTRA)); + } else { + data.insert("path", item.localPath()); + } } if (m_requestRole[IsExpandedRole]) { data.insert("isExpanded", false); } + if (m_requestRole[IsExpandableRole]) { + data.insert("isExpandable", item.isDir() && item.url() == item.targetUrl()); + } + if (m_requestRole[ExpansionLevelRole]) { if (m_rootExpansionLevel == UninitializedRootExpansionLevel && m_dirLister.data()) { const KUrl rootUrl = m_dirLister.data()->url(); const QString protocol = rootUrl.protocol(); - const bool isSearchUrl = (protocol.contains("search") || protocol == QLatin1String("nepomuk")); - if (isSearchUrl) { + const bool forceRootExpansionLevel = (protocol == QLatin1String("trash") || + protocol == QLatin1String("nepomuk") || + protocol == QLatin1String("remote") || + protocol.contains(QLatin1String("search"))); + if (forceRootExpansionLevel) { m_rootExpansionLevel = ForceRootExpansionLevel; } else { const QString rootDir = rootUrl.directory(KUrl::AppendTrailingSlash); @@ -1158,7 +1194,7 @@ QHash KFileItemModel::retrieveData(const KFileItem& item) } if (m_rootExpansionLevel == ForceRootExpansionLevel) { - data.insert("expansionLevel", 0); + data.insert("expansionLevel", -1); } else { const QString dir = item.url().directory(KUrl::AppendTrailingSlash); const int level = dir.count('/') - m_rootExpansionLevel - 1; @@ -1484,9 +1520,9 @@ int KFileItemModel::expansionLevelsCompare(const ItemData* a, const ItemData* b) const QString subPathB = subPath(b->item, pathB, index, &isDirB); if (isDirA && !isDirB) { - return -1; + return (sortOrder() == Qt::AscendingOrder) ? -1 : +1; } else if (!isDirA && isDirB) { - return +1; + return (sortOrder() == Qt::AscendingOrder) ? +1 : -1; } // Compare the items of the parents that represent the first @@ -1549,7 +1585,7 @@ QList > KFileItemModel::nameRoleGroups() const // Use the first character of the name as group indication QChar newFirstChar = name.at(0).toUpper(); if (newFirstChar == QLatin1Char('~') && name.length() > 1) { - newFirstChar = name.at(1); + newFirstChar = name.at(1).toUpper(); } if (firstChar != newFirstChar) { @@ -1842,4 +1878,21 @@ QList > KFileItemModel::genericStringRoleGroups(const QByte return groups; } +KFileItemList KFileItemModel::childItems(const KFileItem& item) const +{ + KFileItemList items; + + int index = m_items.value(item.url(), -1); + if (index >= 0) { + const int parentLevel = m_itemData.at(index)->values.value("expansionLevel").toInt(); + ++index; + while (index < m_itemData.count() && m_itemData.at(index)->values.value("expansionLevel").toInt() > parentLevel) { + items.append(m_itemData.at(index)->item); + ++index; + } + } + + return items; +} + #include "kfileitemmodel.moc"