X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/e615bfaed4cd562d31ea0506529f730c414b6ec0..4d9ea4261a1f24e299595b897ea790eab1748fe9:/src/kitemviews/kfileitemmodelrolesupdater.cpp diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 92a020003..a603a94da 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -1,55 +1,37 @@ -/*************************************************************************** - * Copyright (C) 2011 by Peter Penz * - * * - * 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 * - ***************************************************************************/ +/* + * SPDX-FileCopyrightText: 2011 Peter Penz + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ #include "kfileitemmodelrolesupdater.h" #include "kfileitemmodel.h" +#include "private/kdirectorycontentscounter.h" +#include "private/kpixmapmodifier.h" #include #include -#include -#include -#include -#include #include #include -#include +#include +#include #include +#include +#include -#include "private/kpixmapmodifier.h" -#include "private/kdirectorycontentscounter.h" +#ifdef HAVE_BALOO +#include "private/kbaloorolesprovider.h" +#include +#include +#endif #include +#include #include -#include #include #include -#include - -#ifdef HAVE_BALOO - #include "private/kbaloorolesprovider.h" - #include - #include -#endif - - // #define KFILEITEMMODELROLESUPDATER_DEBUG namespace { @@ -84,25 +66,25 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_roles(), m_resolvableRoles(), m_enabledPlugins(), + m_localFileSizePreviewLimit(0), + m_scanDirectories(true), m_pendingSortRoleItems(), m_pendingIndexes(), m_pendingPreviewItems(), m_previewJob(), - m_recentlyChangedItemsTimer(0), + m_recentlyChangedItemsTimer(nullptr), m_recentlyChangedItems(), m_changedItems(), - m_directoryContentsCounter(0) + m_directoryContentsCounter(nullptr) #ifdef HAVE_BALOO - , m_balooFileMonitor(0) + , m_balooFileMonitor(nullptr) #endif { Q_ASSERT(model); const KConfigGroup globalConfig(KSharedConfig::openConfig(), "PreviewSettings"); - m_enabledPlugins = globalConfig.readEntry("Plugins", QStringList() - << QStringLiteral("directorythumbnail") - << QStringLiteral("imagethumbnail") - << QStringLiteral("jpegthumbnail")); + m_enabledPlugins = globalConfig.readEntry("Plugins", KIO::PreviewJob::defaultPlugins()); + m_localFileSizePreviewLimit = static_cast(globalConfig.readEntry("MaximumSize", 0)); connect(m_model, &KFileItemModel::itemsInserted, this, &KFileItemModelRolesUpdater::slotItemsInserted); @@ -116,9 +98,9 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO this, &KFileItemModelRolesUpdater::slotSortRoleChanged); // Use a timer to prevent that each call of slotItemsChanged() results in a synchronous - // resolving of the roles. Postpone the resolving until no update has been done for 1 second. + // resolving of the roles. Postpone the resolving until no update has been done for 100 ms. m_recentlyChangedItemsTimer = new QTimer(this); - m_recentlyChangedItemsTimer->setInterval(1000); + m_recentlyChangedItemsTimer->setInterval(100); m_recentlyChangedItemsTimer->setSingleShot(true); connect(m_recentlyChangedItemsTimer, &QTimer::timeout, this, &KFileItemModelRolesUpdater::resolveRecentlyChangedItems); @@ -133,8 +115,8 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result, this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived); - auto plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/overlayicon"), nullptr, qApp); - foreach (QObject *it, plugins) { + const auto plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/overlayicon"), nullptr, qApp); + for (QObject *it : plugins) { auto plugin = qobject_cast(it); if (plugin) { m_overlayIconsPlugin.append(plugin); @@ -299,7 +281,7 @@ void KFileItemModelRolesUpdater::setRoles(const QSet& roles) this, &KFileItemModelRolesUpdater::applyChangedBalooRoles); } else if (!hasBalooRole && m_balooFileMonitor) { delete m_balooFileMonitor; - m_balooFileMonitor = 0; + m_balooFileMonitor = nullptr; } #endif @@ -326,6 +308,26 @@ QStringList KFileItemModelRolesUpdater::enabledPlugins() const return m_enabledPlugins; } +void KFileItemModelRolesUpdater::setLocalFileSizePreviewLimit(const qlonglong size) +{ + m_localFileSizePreviewLimit = size; +} + +qlonglong KFileItemModelRolesUpdater::localFileSizePreviewLimit() const +{ + return m_localFileSizePreviewLimit; +} + +void KFileItemModelRolesUpdater::setScanDirectories(bool enabled) +{ + m_scanDirectories = enabled; +} + +bool KFileItemModelRolesUpdater::scanDirectories() const +{ + return m_scanDirectories; +} + void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList& itemRanges) { QElapsedTimer timer; @@ -334,7 +336,7 @@ void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList& itemRan // Determine the sort role synchronously for as many items as possible. if (m_resolvableRoles.contains(m_model->sortRole())) { int insertedCount = 0; - foreach (const KItemRange& range, itemRanges) { + for (const KItemRange& range : itemRanges) { const int lastIndex = insertedCount + range.index + range.count - 1; for (int i = insertedCount + range.index; i <= lastIndex; ++i) { if (timer.elapsed() < MaxBlockTimeout) { @@ -363,7 +365,7 @@ void KFileItemModelRolesUpdater::slotItemsInserted(const KItemRangeList& itemRan void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRanges) { - Q_UNUSED(itemRanges); + Q_UNUSED(itemRanges) const bool allItemsRemoved = (m_model->count() == 0); @@ -374,7 +376,8 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang m_balooFileMonitor->clear(); } else { QStringList newFileList; - foreach (const QString& file, m_balooFileMonitor->files()) { + const QStringList oldFileList = m_balooFileMonitor->files(); + for (const QString& file : oldFileList) { if (m_model->index(QUrl::fromLocalFile(file)) >= 0) { newFileList.append(file); } @@ -413,10 +416,10 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang } } -void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, QList movedToIndexes) +void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, const QList &movedToIndexes) { - Q_UNUSED(itemRange); - Q_UNUSED(movedToIndexes); + Q_UNUSED(itemRange) + Q_UNUSED(movedToIndexes) // The visible items might have changed. startUpdating(); @@ -425,7 +428,7 @@ void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, QLi void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRanges, const QSet& roles) { - Q_UNUSED(roles); + Q_UNUSED(roles) // Find out if slotItemsChanged() has been done recently. If that is the // case, resolving the roles is postponed until a timer has exceeded @@ -434,7 +437,7 @@ void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRang QSet& targetSet = itemsChangedRecently ? m_recentlyChangedItems : m_changedItems; - foreach (const KItemRange& itemRange, itemRanges) { + for (const KItemRange& itemRange : itemRanges) { int index = itemRange.index; for (int count = itemRange.count; count > 0; --count) { const KFileItem item = m_model->fileItem(index); @@ -453,8 +456,8 @@ void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRang void KFileItemModelRolesUpdater::slotSortRoleChanged(const QByteArray& current, const QByteArray& previous) { - Q_UNUSED(current); - Q_UNUSED(previous); + Q_UNUSED(current) + Q_UNUSED(previous) if (m_resolvableRoles.contains(current)) { m_pendingSortRoleItems.clear(); @@ -503,10 +506,9 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi QPixmap scaledPixmap = pixmap; - const QString mimeType = item.mimetype(); - const int slashIndex = mimeType.indexOf(QLatin1Char('/')); - const QString mimeTypeGroup = mimeType.left(slashIndex); - if (mimeTypeGroup == QLatin1String("image")) { + if (!pixmap.hasAlpha() && !pixmap.isNull() + && m_iconSize.width() > KIconLoader::SizeSmallMedium + && m_iconSize.height() > KIconLoader::SizeSmallMedium) { if (m_enlargeSmallPreviews) { KPixmapModifier::applyFrame(scaledPixmap, m_iconSize); } else { @@ -530,13 +532,14 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi scaledPixmap); scaledPixmap = largeFrame; } else { - // The image must be shrinked as it is too large to fit into + // The image must be shrunk as it is too large to fit into // the available icon size KPixmapModifier::applyFrame(scaledPixmap, m_iconSize); } } - } else { - KPixmapModifier::scale(scaledPixmap, m_iconSize); + } else if (!pixmap.isNull()) { + KPixmapModifier::scale(scaledPixmap, m_iconSize * qApp->devicePixelRatio()); + scaledPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); } QHash data = rolesData(item); @@ -547,12 +550,14 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi // It is more efficient to do it here, as KIconLoader::drawOverlays() // assumes that an overlay will be drawn and has some additional // setup time. - foreach (const QString& overlay, overlays) { - if (!overlay.isEmpty()) { - // There is at least one overlay, draw all overlays above m_pixmap - // and cancel the check - KIconLoader::global()->drawOverlays(overlays, scaledPixmap, KIconLoader::Desktop); - break; + if (!scaledPixmap.isNull()) { + for (const QString& overlay : overlays) { + if (!overlay.isEmpty()) { + // There is at least one overlay, draw all overlays above m_pixmap + // and cancel the check + KIconLoader::global()->drawOverlays(overlays, scaledPixmap, KIconLoader::Desktop); + break; + } } } @@ -593,7 +598,7 @@ void KFileItemModelRolesUpdater::slotPreviewFailed(const KFileItem& item) void KFileItemModelRolesUpdater::slotPreviewJobFinished() { - m_previewJob = 0; + m_previewJob = nullptr; if (m_state != PreviewJobRunning) { return; @@ -718,6 +723,8 @@ void KFileItemModelRolesUpdater::applyChangedBalooRoles(const QString& file) return; } applyChangedBalooRolesForItem(item); +#else + Q_UNUSED(file) #endif } @@ -730,7 +737,8 @@ void KFileItemModelRolesUpdater::applyChangedBalooRolesForItem(const KFileItem & const KBalooRolesProvider& rolesProvider = KBalooRolesProvider::instance(); QHash data; - foreach (const QByteArray& role, rolesProvider.roles()) { + const auto roles = rolesProvider.roles(); + for (const QByteArray& role : roles) { // Overwrite all the role values with an empty QVariant, because the roles // provider doesn't overwrite it when the property value list is empty. // See bug 322348 @@ -751,12 +759,12 @@ void KFileItemModelRolesUpdater::applyChangedBalooRolesForItem(const KFileItem & this, &KFileItemModelRolesUpdater::slotItemsChanged); #else #ifndef Q_CC_MSVC - Q_UNUSED(item); + Q_UNUSED(item) #endif #endif } -void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString& path, int count) +void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QString& path, int count, long size) { const bool getSizeRole = m_roles.contains("size"); const bool getIsExpandableRole = m_roles.contains("isExpandable"); @@ -767,7 +775,8 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin QHash data; if (getSizeRole) { - data.insert("size", count); + data.insert("count", count); + data.insert("size", QVariant::fromValue(size)); } if (getIsExpandableRole) { data.insert("isExpandable", count > 0); @@ -777,7 +786,7 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin this, &KFileItemModelRolesUpdater::slotItemsChanged); m_model->setData(index, data); connect(m_model, &KFileItemModel::itemsChanged, - this, &KFileItemModelRolesUpdater::slotItemsChanged); + this, &KFileItemModelRolesUpdater::slotItemsChanged); } } } @@ -817,7 +826,7 @@ void KFileItemModelRolesUpdater::startUpdating() m_pendingPreviewItems.clear(); m_pendingPreviewItems.reserve(indexes.count()); - foreach (int index, indexes) { + for (int index : qAsConst(indexes)) { const KFileItem item = m_model->fileItem(index); if (!m_finishedItems.contains(item)) { m_pendingPreviewItems.append(item); @@ -906,8 +915,8 @@ void KFileItemModelRolesUpdater::startPreviewJob() KIO::PreviewJob* job = new KIO::PreviewJob(itemSubSet, cacheSize, &m_enabledPlugins); - job->setIgnoreMaximumSize(itemSubSet.first().isLocalFile()); - if (job->ui()) { + job->setIgnoreMaximumSize(itemSubSet.first().isLocalFile() && m_localFileSizePreviewLimit <= 0); + if (job->uiDelegate()) { KJobWidgets::setWindow(job, qApp->activeWindow()); } @@ -949,14 +958,19 @@ void KFileItemModelRolesUpdater::updateChangedItems() QList visibleChangedIndexes; QList invisibleChangedIndexes; + visibleChangedIndexes.reserve(m_changedItems.size()); + invisibleChangedIndexes.reserve(m_changedItems.size()); - foreach (const KFileItem& item, m_changedItems) { + auto changedItemsIt = m_changedItems.begin(); + while (changedItemsIt != m_changedItems.end()) { + const auto& item = *changedItemsIt; const int index = m_model->index(item); if (index < 0) { - m_changedItems.remove(item); + changedItemsIt = m_changedItems.erase(changedItemsIt); continue; } + ++changedItemsIt; if (index >= m_firstVisibleIndex && index <= m_lastVisibleIndex) { visibleChangedIndexes.append(index); @@ -968,11 +982,11 @@ void KFileItemModelRolesUpdater::updateChangedItems() std::sort(visibleChangedIndexes.begin(), visibleChangedIndexes.end()); if (m_previewShown) { - foreach (int index, visibleChangedIndexes) { + for (int index : qAsConst(visibleChangedIndexes)) { m_pendingPreviewItems.append(m_model->fileItem(index)); } - foreach (int index, invisibleChangedIndexes) { + for (int index : qAsConst(invisibleChangedIndexes)) { m_pendingPreviewItems.append(m_model->fileItem(index)); } @@ -1003,7 +1017,9 @@ void KFileItemModelRolesUpdater::applySortRole(int index) data.insert("type", item.mimeComment()); } else if (m_model->sortRole() == "size" && item.isLocalFile() && item.isDir()) { const QString path = item.localPath(); - data.insert("size", m_directoryContentsCounter->countDirectoryContentsSynchronously(path)); + if (m_scanDirectories) { + m_directoryContentsCounter->scanDirectory(path); + } } else { // Probably the sort role is a baloo role - just determine all roles. data = rolesData(item); @@ -1047,7 +1063,9 @@ bool KFileItemModelRolesUpdater::applyResolvedRoles(int index, ResolveHint hint) data = rolesData(item); } - data.insert("iconName", item.iconName()); + if (!item.iconName().isEmpty()) { + data.insert("iconName", item.iconName()); + } if (m_clearPreviews) { data.insert("iconPixmap", QPixmap()); @@ -1075,8 +1093,10 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte if (item.isLocalFile()) { // Tell m_directoryContentsCounter that we want to count the items // inside the directory. The result will be received in slotDirectoryContentsCountReceived. - const QString path = item.localPath(); - m_directoryContentsCounter->addDirectory(path); + if (m_scanDirectories) { + const QString path = item.localPath(); + m_directoryContentsCounter->scanDirectory(path); + } } else if (getSizeRole) { data.insert("size", -1); // -1 indicates an unknown number of items } @@ -1087,7 +1107,7 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte } QStringList overlays = item.overlays(); - foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) { + for (KOverlayIconPlugin *it : qAsConst(m_overlayIconsPlugin)) { overlays.append(it->getOverlays(item.url())); } data.insert("iconOverlays", overlays); @@ -1110,7 +1130,7 @@ void KFileItemModelRolesUpdater::slotOverlaysChanged(const QUrl& url, const QStr const int index = m_model->index(item); QHash data = m_model->data(index); QStringList overlays = item.overlays(); - foreach (KOverlayIconPlugin *it, m_overlayIconsPlugin) { + for (KOverlayIconPlugin *it : qAsConst(m_overlayIconsPlugin)) { overlays.append(it->getOverlays(url)); } data.insert("iconOverlays", overlays); @@ -1137,7 +1157,7 @@ void KFileItemModelRolesUpdater::killPreviewJob() disconnect(m_previewJob, &KIO::PreviewJob::finished, this, &KFileItemModelRolesUpdater::slotPreviewJobFinished); m_previewJob->kill(); - m_previewJob = 0; + m_previewJob = nullptr; m_pendingPreviewItems.clear(); } } @@ -1147,7 +1167,9 @@ QList KFileItemModelRolesUpdater::indexesToResolve() const const int count = m_model->count(); QList result; - result.reserve(ResolveAllItemsLimit); + result.reserve(qMin(count, (m_lastVisibleIndex - m_firstVisibleIndex + 1) + + ResolveAllItemsLimit + + (2 * m_maximumVisibleItems))); // Add visible items. for (int i = m_firstVisibleIndex; i <= m_lastVisibleIndex; ++i) { @@ -1156,7 +1178,7 @@ QList KFileItemModelRolesUpdater::indexesToResolve() const // We need a reasonable upper limit for number of items to resolve after // and before the visible range. m_maximumVisibleItems can be quite large - // when using Compace View. + // when using Compact View. const int readAheadItems = qMin(ReadAheadPages * m_maximumVisibleItems, ResolveAllItemsLimit / 2); // Add items after the visible range. @@ -1172,14 +1194,14 @@ QList KFileItemModelRolesUpdater::indexesToResolve() const } // Add items on the last page. - const int beginLastPage = qMax(qMin(endExtendedVisibleRange + 1, count - 1), count - m_maximumVisibleItems); + const int beginLastPage = qMax(endExtendedVisibleRange + 1, count - m_maximumVisibleItems); for (int i = beginLastPage; i < count; ++i) { result.append(i); } // Add items on the first page. - const int endFirstPage = qMin(qMax(beginExtendedVisibleRange - 1, 0), m_maximumVisibleItems); - for (int i = 0; i <= endFirstPage; ++i) { + const int endFirstPage = qMin(beginExtendedVisibleRange, m_maximumVisibleItems); + for (int i = 0; i < endFirstPage; ++i) { result.append(i); } @@ -1191,7 +1213,7 @@ QList KFileItemModelRolesUpdater::indexesToResolve() const --remainingItems; } - for (int i = beginExtendedVisibleRange - 1; i > endFirstPage && remainingItems > 0; --i) { + for (int i = beginExtendedVisibleRange - 1; i >= endFirstPage && remainingItems > 0; --i) { result.append(i); --remainingItems; }