X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/blobdiff_plain/1b4572dac9fb529d31b786f93e4f02c6f8aeeb21..e6ea3ab4c41dcc115143a237aafd3a1152849433:/src/kitemviews/kfileitemmodelrolesupdater.cpp diff --git a/src/kitemviews/kfileitemmodelrolesupdater.cpp b/src/kitemviews/kfileitemmodelrolesupdater.cpp index 2353f106f..c28e240a5 100644 --- a/src/kitemviews/kfileitemmodelrolesupdater.cpp +++ b/src/kitemviews/kfileitemmodelrolesupdater.cpp @@ -20,33 +20,30 @@ #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 "private/kpixmapmodifier.h" -#include "private/kdirectorycontentscounter.h" +#ifdef HAVE_BALOO +#include "private/kbaloorolesprovider.h" +#include +#include +#endif #include #include -#include #include #include -#include - -#ifdef HAVE_BALOO - #include "private/kbaloorolesprovider.h" - #include - #include -#endif - // #define KFILEITEMMODELROLESUPDATER_DEBUG namespace { @@ -85,21 +82,18 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO 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() - << "directorythumbnail" - << "imagethumbnail" - << "jpegthumbnail"); + m_enabledPlugins = globalConfig.readEntry("Plugins", KIO::PreviewJob::defaultPlugins()); connect(m_model, &KFileItemModel::itemsInserted, this, &KFileItemModelRolesUpdater::slotItemsInserted); @@ -113,9 +107,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); @@ -129,6 +123,18 @@ KFileItemModelRolesUpdater::KFileItemModelRolesUpdater(KFileItemModel* model, QO m_directoryContentsCounter = new KDirectoryContentsCounter(m_model, this); connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result, this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived); + + auto plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/overlayicon"), nullptr, qApp); + foreach (QObject *it, plugins) { + auto plugin = qobject_cast(it); + if (plugin) { + m_overlayIconsPlugin.append(plugin); + connect(plugin, &KOverlayIconPlugin::overlaysChanged, this, &KFileItemModelRolesUpdater::slotOverlaysChanged); + } else { + // not our/valid plugin, so delete the created object + it->deleteLater(); + } + } } KFileItemModelRolesUpdater::~KFileItemModelRolesUpdater() @@ -278,13 +284,13 @@ void KFileItemModelRolesUpdater::setRoles(const QSet& roles) } } - if (hasBalooRole && !m_balooFileMonitor) { + if (hasBalooRole && m_balooConfig.fileIndexingEnabled() && !m_balooFileMonitor) { m_balooFileMonitor = new Baloo::FileMonitor(this); connect(m_balooFileMonitor, &Baloo::FileMonitor::fileMetaDataChanged, this, &KFileItemModelRolesUpdater::applyChangedBalooRoles); } else if (!hasBalooRole && m_balooFileMonitor) { delete m_balooFileMonitor; - m_balooFileMonitor = 0; + m_balooFileMonitor = nullptr; } #endif @@ -348,7 +354,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); @@ -359,9 +365,9 @@ void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRang m_balooFileMonitor->clear(); } else { QStringList newFileList; - foreach (const QString& itemUrl, m_balooFileMonitor->files()) { - if (m_model->index(itemUrl) >= 0) { - newFileList.append(itemUrl); + foreach (const QString& file, m_balooFileMonitor->files()) { + if (m_model->index(QUrl::fromLocalFile(file)) >= 0) { + newFileList.append(file); } } m_balooFileMonitor->setFiles(newFileList); @@ -398,10 +404,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(); @@ -410,7 +416,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 @@ -438,8 +444,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(); @@ -488,10 +494,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() + && m_iconSize.width() > KIconLoader::SizeSmallMedium + && m_iconSize.height() > KIconLoader::SizeSmallMedium) { if (m_enlargeSmallPreviews) { KPixmapModifier::applyFrame(scaledPixmap, m_iconSize); } else { @@ -501,7 +506,7 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi const bool enlargingRequired = scaledPixmap.width() < contentSize.width() && scaledPixmap.height() < contentSize.height(); if (enlargingRequired) { - QSize frameSize = scaledPixmap.size(); + QSize frameSize = scaledPixmap.size() / scaledPixmap.devicePixelRatio(); frameSize.scale(m_iconSize, Qt::KeepAspectRatio); QPixmap largeFrame(frameSize); @@ -510,18 +515,19 @@ void KFileItemModelRolesUpdater::slotGotPreview(const KFileItem& item, const QPi KPixmapModifier::applyFrame(largeFrame, frameSize); QPainter painter(&largeFrame); - painter.drawPixmap((largeFrame.width() - scaledPixmap.width()) / 2, - (largeFrame.height() - scaledPixmap.height()) / 2, + painter.drawPixmap((largeFrame.width() - scaledPixmap.width() / scaledPixmap.devicePixelRatio()) / 2, + (largeFrame.height() - scaledPixmap.height() / scaledPixmap.devicePixelRatio()) / 2, 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); + KPixmapModifier::scale(scaledPixmap, m_iconSize * qApp->devicePixelRatio()); + scaledPixmap.setDevicePixelRatio(qApp->devicePixelRatio()); } QHash data = rolesData(item); @@ -578,7 +584,7 @@ void KFileItemModelRolesUpdater::slotPreviewFailed(const KFileItem& item) void KFileItemModelRolesUpdater::slotPreviewJobFinished() { - m_previewJob = 0; + m_previewJob = nullptr; if (m_state != PreviewJobRunning) { return; @@ -620,7 +626,7 @@ void KFileItemModelRolesUpdater::resolveNextSortRole() if (!m_pendingSortRoleItems.isEmpty()) { applySortProgressToModel(); - QTimer::singleShot(0, this, SLOT(resolveNextSortRole())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextSortRole); } else { m_state = Idle; @@ -655,7 +661,7 @@ void KFileItemModelRolesUpdater::resolveNextPendingRoles() } if (!m_pendingIndexes.isEmpty()) { - QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextPendingRoles); } else { m_state = Idle; @@ -692,17 +698,25 @@ void KFileItemModelRolesUpdater::resolveRecentlyChangedItems() updateChangedItems(); } -void KFileItemModelRolesUpdater::applyChangedBalooRoles(const QString& itemUrl) +void KFileItemModelRolesUpdater::applyChangedBalooRoles(const QString& file) { #ifdef HAVE_BALOO - const KFileItem item = m_model->fileItem(itemUrl); + const KFileItem item = m_model->fileItem(QUrl::fromLocalFile(file)); if (item.isNull()) { // itemUrl is not in the model anymore, probably because // the corresponding file has been deleted in the meantime. return; } + applyChangedBalooRolesForItem(item); +#else + Q_UNUSED(file) +#endif +} +void KFileItemModelRolesUpdater::applyChangedBalooRolesForItem(const KFileItem &item) +{ +#ifdef HAVE_BALOO Baloo::File file(item.localPath()); file.load(); @@ -730,12 +744,12 @@ void KFileItemModelRolesUpdater::applyChangedBalooRoles(const QString& itemUrl) this, &KFileItemModelRolesUpdater::slotItemsChanged); #else #ifndef Q_CC_MSVC - Q_UNUSED(itemUrl); + 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"); @@ -746,17 +760,16 @@ void KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived(const QStrin QHash data; if (getSizeRole) { - data.insert("size", count); + data.insert("count", count); + if (size != -1) { + data.insert("size", QVariant::fromValue(size)); + } } if (getIsExpandableRole) { data.insert("isExpandable", count > 0); } - disconnect(m_model, &KFileItemModel::itemsChanged, - this, &KFileItemModelRolesUpdater::slotItemsChanged); m_model->setData(index, data); - connect(m_model, &KFileItemModel::itemsChanged, - this, &KFileItemModelRolesUpdater::slotItemsChanged); } } } @@ -808,7 +821,7 @@ void KFileItemModelRolesUpdater::startUpdating() m_pendingIndexes = indexes; // Trigger the asynchronous resolving of all roles. m_state = ResolvingAllRoles; - QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextPendingRoles); } } @@ -843,7 +856,7 @@ void KFileItemModelRolesUpdater::startPreviewJob() m_state = PreviewJobRunning; if (m_pendingPreviewItems.isEmpty()) { - QTimer::singleShot(0, this, SLOT(slotPreviewJobFinished())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::slotPreviewJobFinished); return; } @@ -886,7 +899,7 @@ void KFileItemModelRolesUpdater::startPreviewJob() KIO::PreviewJob* job = new KIO::PreviewJob(itemSubSet, cacheSize, &m_enabledPlugins); job->setIgnoreMaximumSize(itemSubSet.first().isLocalFile()); - if (job->ui()) { + if (job->uiDelegate()) { KJobWidgets::setWindow(job, qApp->activeWindow()); } @@ -920,7 +933,7 @@ void KFileItemModelRolesUpdater::updateChangedItems() // asynchronous determination of the sort role. killPreviewJob(); m_state = ResolvingSortRole; - QTimer::singleShot(0, this, SLOT(resolveNextSortRole())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextSortRole); } return; @@ -964,7 +977,7 @@ void KFileItemModelRolesUpdater::updateChangedItems() if (!resolvingInProgress) { // Trigger the asynchronous resolving of the changed roles. m_state = ResolvingAllRoles; - QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles())); + QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextPendingRoles); } } } @@ -982,7 +995,7 @@ 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)); + m_directoryContentsCounter->scanDirectory(path); } else { // Probably the sort role is a baloo role - just determine all roles. data = rolesData(item); @@ -1055,7 +1068,7 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte // 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); + m_directoryContentsCounter->scanDirectory(path); } else if (getSizeRole) { data.insert("size", -1); // -1 indicates an unknown number of items } @@ -1065,17 +1078,37 @@ QHash KFileItemModelRolesUpdater::rolesData(const KFileIte data.insert("type", item.mimeComment()); } - data.insert("iconOverlays", item.overlays()); + QStringList overlays = item.overlays(); + foreach(KOverlayIconPlugin *it, m_overlayIconsPlugin) { + overlays.append(it->getOverlays(item.url())); + } + data.insert("iconOverlays", overlays); #ifdef HAVE_BALOO if (m_balooFileMonitor) { m_balooFileMonitor->addFile(item.localPath()); - applyChangedBalooRoles(item.localPath()); + applyChangedBalooRolesForItem(item); } #endif return data; } +void KFileItemModelRolesUpdater::slotOverlaysChanged(const QUrl& url, const QStringList &) +{ + const KFileItem item = m_model->fileItem(url); + if (item.isNull()) { + return; + } + const int index = m_model->index(item); + QHash data = m_model->data(index); + QStringList overlays = item.overlays(); + foreach (KOverlayIconPlugin *it, m_overlayIconsPlugin) { + overlays.append(it->getOverlays(url)); + } + data.insert("iconOverlays", overlays); + m_model->setData(index, data); +} + void KFileItemModelRolesUpdater::updateAllPreviews() { if (m_state == Paused) { @@ -1096,7 +1129,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(); } } @@ -1115,7 +1148,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.