-/***************************************************************************
- * Copyright (C) 2011 by Peter Penz <peter.penz19@gmail.com> *
- * *
- * 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 <peter.penz19@gmail.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
#include "kfileitemlistview.h"
-#include "kfileitemmodelrolesupdater.h"
#include "kfileitemlistwidget.h"
#include "kfileitemmodel.h"
+#include "kfileitemmodelrolesupdater.h"
+#include "private/kitemviewsutils.h"
#include "private/kpixmapmodifier.h"
#include <KIconLoader>
-#include <QPainter>
-#include <QTimer>
#include <QGraphicsScene>
#include <QGraphicsView>
+#include <QIcon>
+#include <QMimeDatabase>
+#include <QPainter>
+#include <QTimer>
// #define KFILEITEMLISTVIEW_DEBUG
-namespace {
- // If the visible index range changes, KFileItemModelRolesUpdater is not
- // informed immediatetly, but with a short delay. This ensures that scrolling
- // always feels smooth and is not interrupted by icon loading (which can be
- // quite expensive if a disk access is required to determine the final icon).
- const int ShortInterval = 50;
-
- // If the icon size changes, a longer delay is used. This prevents that
- // the expensive re-generation of all previews is triggered repeatedly when
- // changing the zoom level.
- const int LongInterval = 300;
-}
-
-KFileItemListView::KFileItemListView(QGraphicsWidget* parent) :
- KStandardItemListView(parent),
- m_modelRolesUpdater(nullptr),
- m_updateVisibleIndexRangeTimer(nullptr),
- m_updateIconSizeTimer(nullptr)
+namespace
+{
+// If the visible index range changes, KFileItemModelRolesUpdater is not
+// informed immediately, but with a short delay. This ensures that scrolling
+// always feels smooth and is not interrupted by icon loading (which can be
+// quite expensive if a disk access is required to determine the final icon).
+const int ShortInterval = 50;
+
+// If the icon size changes, a longer delay is used. This prevents that
+// the expensive re-generation of all previews is triggered repeatedly when
+// changing the zoom level.
+const int LongInterval = 300;
+}
+
+KFileItemListView::KFileItemListView(QGraphicsWidget *parent)
+ : KStandardItemListView(parent)
+ , m_modelRolesUpdater(nullptr)
+ , m_updateVisibleIndexRangeTimer(nullptr)
+ , m_updateIconSizeTimer(nullptr)
{
setAcceptDrops(true);
return m_modelRolesUpdater ? m_modelRolesUpdater->enlargeSmallPreviews() : false;
}
-void KFileItemListView::setEnabledPlugins(const QStringList& list)
+void KFileItemListView::setEnabledPlugins(const QStringList &list)
{
if (m_modelRolesUpdater) {
m_modelRolesUpdater->setEnabledPlugins(list);
return m_modelRolesUpdater ? m_modelRolesUpdater->enabledPlugins() : QStringList();
}
-QPixmap KFileItemListView::createDragPixmap(const KItemSet& indexes) const
+void KFileItemListView::setLocalFileSizePreviewLimit(const qlonglong size)
+{
+ if (m_modelRolesUpdater) {
+ m_modelRolesUpdater->setLocalFileSizePreviewLimit(size);
+ }
+}
+
+qlonglong KFileItemListView::localFileSizePreviewLimit() const
+{
+ return m_modelRolesUpdater ? m_modelRolesUpdater->localFileSizePreviewLimit() : 0;
+}
+
+QPixmap KFileItemListView::createDragPixmap(const KItemSet &indexes) const
{
if (!model()) {
return QPixmap();
yCount = xCount;
}
- const qreal dpr = scene()->views()[0]->devicePixelRatio();
+ const qreal dpr = KItemViewsUtils::devicePixelRatio(this);
// Draw the selected items into the grid cells.
QPixmap dragPixmap(QSize(xCount * size + xCount, yCount * size + yCount) * dpr);
dragPixmap.setDevicePixelRatio(dpr);
QPixmap pixmap = model()->data(index).value("iconPixmap").value<QPixmap>();
if (pixmap.isNull()) {
QIcon icon = QIcon::fromTheme(model()->data(index).value("iconName").toString());
- pixmap = icon.pixmap(size, size);
+ if (icon.isNull()) {
+ icon = QIcon::fromTheme(QStringLiteral("unknown"));
+ }
+ if (!icon.isNull()) {
+ pixmap = icon.pixmap(size, size);
+ } else {
+ pixmap = QPixmap(size, size);
+ pixmap.fill(Qt::transparent);
+ }
} else {
KPixmapModifier::scale(pixmap, QSize(size, size) * dpr);
}
return dragPixmap;
}
-KItemListWidgetCreatorBase* KFileItemListView::defaultWidgetCreator() const
+void KFileItemListView::setHoverSequenceState(const QUrl &itemUrl, int seqIdx)
+{
+ if (m_modelRolesUpdater) {
+ m_modelRolesUpdater->setHoverSequenceState(itemUrl, seqIdx);
+ }
+}
+
+KItemListWidgetCreatorBase *KFileItemListView::defaultWidgetCreator() const
{
return new KItemListWidgetCreator<KFileItemListWidget>();
}
-void KFileItemListView::initializeItemListWidget(KItemListWidget* item)
+void KFileItemListView::initializeItemListWidget(KItemListWidget *item)
{
KStandardItemListView::initializeItemListWidget(item);
// Make sure that the item has an icon.
QHash<QByteArray, QVariant> data = item->data();
if (!data.contains("iconName") && data["iconPixmap"].value<QPixmap>().isNull()) {
- Q_ASSERT(qobject_cast<KFileItemModel*>(model()));
- KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(model());
+ Q_ASSERT(qobject_cast<KFileItemModel *>(model()));
+ KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(model());
const KFileItem fileItem = fileItemModel->fileItem(item->index());
- data.insert("iconName", fileItem.iconName());
+ QString iconName = fileItem.iconName();
+ if (!QIcon::hasThemeIcon(iconName)) {
+ QMimeDatabase mimeDb;
+ iconName = mimeDb.mimeTypeForName(fileItem.mimetype()).genericIconName();
+ }
+ data.insert("iconName", iconName);
item->setData(data, {"iconName"});
}
}
void KFileItemListView::onPreviewsShownChanged(bool shown)
{
- Q_UNUSED(shown);
+ Q_UNUSED(shown)
}
void KFileItemListView::onItemLayoutChanged(ItemLayout current, ItemLayout previous)
triggerVisibleIndexRangeUpdate();
}
-void KFileItemListView::onModelChanged(KItemModelBase* current, KItemModelBase* previous)
+void KFileItemListView::onModelChanged(KItemModelBase *current, KItemModelBase *previous)
{
- Q_ASSERT(qobject_cast<KFileItemModel*>(current));
+ Q_ASSERT(qobject_cast<KFileItemModel *>(current));
KStandardItemListView::onModelChanged(current, previous);
delete m_modelRolesUpdater;
m_modelRolesUpdater = nullptr;
if (current) {
- m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel*>(current), this);
+ m_modelRolesUpdater = new KFileItemModelRolesUpdater(static_cast<KFileItemModel *>(current), this);
m_modelRolesUpdater->setIconSize(availableIconSize());
+ m_modelRolesUpdater->setDevicePixelRatio(KItemViewsUtils::devicePixelRatio(this));
applyRolesToModel();
}
triggerVisibleIndexRangeUpdate();
}
-void KFileItemListView::onItemSizeChanged(const QSizeF& current, const QSizeF& previous)
+void KFileItemListView::onItemSizeChanged(const QSizeF ¤t, const QSizeF &previous)
{
- Q_UNUSED(current);
- Q_UNUSED(previous);
+ Q_UNUSED(current)
+ Q_UNUSED(previous)
triggerVisibleIndexRangeUpdate();
}
triggerVisibleIndexRangeUpdate();
}
-void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray>& current, const QList<QByteArray>& previous)
+void KFileItemListView::onVisibleRolesChanged(const QList<QByteArray> ¤t, const QList<QByteArray> &previous)
{
KStandardItemListView::onVisibleRolesChanged(current, previous);
applyRolesToModel();
}
-void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous)
+void KFileItemListView::onStyleOptionChanged(const KItemListStyleOption ¤t, const KItemListStyleOption &previous)
{
KStandardItemListView::onStyleOptionChanged(current, previous);
triggerIconSizeUpdate();
// Only unpause the model-roles-updater if no timer is active. If one
// timer is still active the model-roles-updater will be unpaused later as
// soon as the timer has been exceeded.
- const bool timerActive = m_updateVisibleIndexRangeTimer->isActive() ||
- m_updateIconSizeTimer->isActive();
+ const bool timerActive = m_updateVisibleIndexRangeTimer->isActive() || m_updateIconSizeTimer->isActive();
if (!timerActive) {
m_modelRolesUpdater->setPaused(false);
}
}
-void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent* event)
+void KFileItemListView::resizeEvent(QGraphicsSceneResizeEvent *event)
{
KStandardItemListView::resizeEvent(event);
triggerVisibleIndexRangeUpdate();
}
-void KFileItemListView::slotItemsRemoved(const KItemRangeList& itemRanges)
+void KFileItemListView::focusInEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event)
+ updateSelectedWidgets();
+}
+
+void KFileItemListView::focusOutEvent(QFocusEvent *event)
+{
+ Q_UNUSED(event)
+ updateSelectedWidgets();
+}
+
+void KFileItemListView::updateSelectedWidgets()
+{
+ const auto visibleWidgets = visibleItemListWidgets();
+ for (KItemListWidget *widget : visibleWidgets) {
+ if (widget->isSelected()) {
+ auto w = qobject_cast<KFileItemListWidget *>(widget);
+ if (w) {
+ w->forceUpdate();
+ }
+ }
+ }
+}
+
+void KFileItemListView::slotItemsRemoved(const KItemRangeList &itemRanges)
{
KStandardItemListView::slotItemsRemoved(itemRanges);
}
-void KFileItemListView::slotSortRoleChanged(const QByteArray& current, const QByteArray& previous)
+void KFileItemListView::slotSortRoleChanged(const QByteArray ¤t, const QByteArray &previous)
{
const QByteArray sortRole = model()->sortRole();
if (!visibleRoles().contains(sortRole)) {
}
m_modelRolesUpdater->setIconSize(availableIconSize());
+ m_modelRolesUpdater->setDevicePixelRatio(KItemViewsUtils::devicePixelRatio(this));
// Update the visible index range (which has most likely changed after the
// icon size change) before unpausing m_modelRolesUpdater.
return;
}
- Q_ASSERT(qobject_cast<KFileItemModel*>(model()));
- KFileItemModel* fileItemModel = static_cast<KFileItemModel*>(model());
+ Q_ASSERT(qobject_cast<KFileItemModel *>(model()));
+ KFileItemModel *fileItemModel = static_cast<KFileItemModel *>(model());
// KFileItemModel does not distinct between "visible" and "invisible" roles.
// Add all roles that are mandatory for having a working KFileItemListView:
- QSet<QByteArray> roles = visibleRoles().toSet();
+ const auto visibleRoles = this->visibleRoles();
+ auto roles = QSet<QByteArray>(visibleRoles.constBegin(), visibleRoles.constEnd());
roles.insert("iconPixmap");
roles.insert("iconName");
roles.insert("text");
roles.insert("expandedParentsCount");
}
- // Assure that the role that is used for sorting will be determined
+ // Assure that the roles used for sorting and grouping will be determined
roles.insert(fileItemModel->sortRole());
+ roles.insert(fileItemModel->groupRole());
fileItemModel->setRoles(roles);
m_modelRolesUpdater->setRoles(roles);
QSize KFileItemListView::availableIconSize() const
{
- const KItemListStyleOption& option = styleOption();
+ const KItemListStyleOption &option = styleOption();
const int iconSize = option.iconSize;
if (itemLayout() == IconsLayout) {
const int maxIconWidth = itemSize().width() - 2 * option.padding;
return QSize(iconSize, iconSize);
}
+#include "moc_kfileitemlistview.cpp"