#include "kfileitemmodelrolesupdater.h"
#include "kfileitemmodel.h"
+#include "private/kdirectorycontentscounter.h"
+#include "private/kpixmapmodifier.h"
#include <KConfig>
#include <KConfigGroup>
-#include <KSharedConfig>
-#include <KFileItem>
-#include <KIconLoader>
-#include <KJobWidgets>
#include <KIO/JobUiDelegate>
#include <KIO/PreviewJob>
-#include <KPluginLoader>
+#include <KIconLoader>
+#include <KJobWidgets>
#include <KOverlayIconPlugin>
+#include <KPluginLoader>
+#include <KSharedConfig>
-#include "private/kpixmapmodifier.h"
-#include "private/kdirectorycontentscounter.h"
+#ifdef HAVE_BALOO
+#include "private/kbaloorolesprovider.h"
+#include <Baloo/File>
+#include <Baloo/FileMonitor>
+#endif
#include <QApplication>
#include <QPainter>
-#include <QPixmap>
#include <QElapsedTimer>
#include <QTimer>
-#include <algorithm>
-
-#ifdef HAVE_BALOO
- #include "private/kbaloorolesprovider.h"
- #include <Baloo/File>
- #include <Baloo/FileMonitor>
-#endif
-
-
// #define KFILEITEMMODELROLESUPDATER_DEBUG
namespace {
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);
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);
connect(m_directoryContentsCounter, &KDirectoryContentsCounter::result,
this, &KFileItemModelRolesUpdater::slotDirectoryContentsCountReceived);
- auto plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/overlayicon"), nullptr, this);
+ auto plugins = KPluginLoader::instantiatePlugins(QStringLiteral("kf5/overlayicon"), nullptr, qApp);
foreach (QObject *it, plugins) {
auto plugin = qobject_cast<KOverlayIconPlugin*>(it);
if (plugin) {
this, &KFileItemModelRolesUpdater::applyChangedBalooRoles);
} else if (!hasBalooRole && m_balooFileMonitor) {
delete m_balooFileMonitor;
- m_balooFileMonitor = 0;
+ m_balooFileMonitor = nullptr;
}
#endif
void KFileItemModelRolesUpdater::slotItemsRemoved(const KItemRangeList& itemRanges)
{
- Q_UNUSED(itemRanges);
+ Q_UNUSED(itemRanges)
const bool allItemsRemoved = (m_model->count() == 0);
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);
}
}
-void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, QList<int> movedToIndexes)
+void KFileItemModelRolesUpdater::slotItemsMoved(const KItemRange& itemRange, const QList<int> &movedToIndexes)
{
- Q_UNUSED(itemRange);
- Q_UNUSED(movedToIndexes);
+ Q_UNUSED(itemRange)
+ Q_UNUSED(movedToIndexes)
// The visible items might have changed.
startUpdating();
void KFileItemModelRolesUpdater::slotItemsChanged(const KItemRangeList& itemRanges,
const QSet<QByteArray>& 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
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();
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 {
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<QByteArray, QVariant> data = rolesData(item);
void KFileItemModelRolesUpdater::slotPreviewJobFinished()
{
- m_previewJob = 0;
+ m_previewJob = nullptr;
if (m_state != PreviewJobRunning) {
return;
if (!m_pendingSortRoleItems.isEmpty()) {
applySortProgressToModel();
- QTimer::singleShot(0, this, SLOT(resolveNextSortRole()));
+ QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextSortRole);
} else {
m_state = Idle;
}
if (!m_pendingIndexes.isEmpty()) {
- QTimer::singleShot(0, this, SLOT(resolveNextPendingRoles()));
+ QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextPendingRoles);
} else {
m_state = Idle;
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
return;
}
applyChangedBalooRolesForItem(item);
+#else
+ Q_UNUSED(file)
#endif
}
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");
QHash<QByteArray, QVariant> 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);
}
}
}
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);
}
}
m_state = PreviewJobRunning;
if (m_pendingPreviewItems.isEmpty()) {
- QTimer::singleShot(0, this, SLOT(slotPreviewJobFinished()));
+ QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::slotPreviewJobFinished);
return;
}
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());
}
// asynchronous determination of the sort role.
killPreviewJob();
m_state = ResolvingSortRole;
- QTimer::singleShot(0, this, SLOT(resolveNextSortRole()));
+ QTimer::singleShot(0, this, &KFileItemModelRolesUpdater::resolveNextSortRole);
}
return;
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);
}
}
}
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);
// 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
}
disconnect(m_previewJob, &KIO::PreviewJob::finished,
this, &KFileItemModelRolesUpdater::slotPreviewJobFinished);
m_previewJob->kill();
- m_previewJob = 0;
+ m_previewJob = nullptr;
m_pendingPreviewItems.clear();
}
}
// 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.