diff options
Diffstat (limited to 'src/gui/image/qabstractfileiconprovider.cpp')
-rw-r--r-- | src/gui/image/qabstractfileiconprovider.cpp | 197 |
1 files changed, 129 insertions, 68 deletions
diff --git a/src/gui/image/qabstractfileiconprovider.cpp b/src/gui/image/qabstractfileiconprovider.cpp index 51638f69d8..71b6a0b03d 100644 --- a/src/gui/image/qabstractfileiconprovider.cpp +++ b/src/gui/image/qabstractfileiconprovider.cpp @@ -1,47 +1,15 @@ -/**************************************************************************** -** -** Copyright (C) 2020 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtGui module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ +// Copyright (C) 2020 The Qt Company Ltd. +// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only #include "qabstractfileiconprovider.h" #include <qguiapplication.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformtheme.h> #include <qicon.h> +#if QT_CONFIG(mimetype) #include <qmimedatabase.h> +#endif #include <private/qabstractfileiconprovider_p.h> @@ -49,12 +17,115 @@ QT_BEGIN_NAMESPACE +using namespace Qt::StringLiterals; + QAbstractFileIconProviderPrivate::QAbstractFileIconProviderPrivate(QAbstractFileIconProvider *q) : q_ptr(q) {} QAbstractFileIconProviderPrivate::~QAbstractFileIconProviderPrivate() = default; +using IconTypeCache = QHash<QAbstractFileIconProvider::IconType, QIcon>; +Q_GLOBAL_STATIC(IconTypeCache, iconTypeCache) + +void QAbstractFileIconProviderPrivate::clearIconTypeCache() +{ + iconTypeCache()->clear(); +} + +QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(QAbstractFileIconProvider::IconType type) const +{ + auto theme = QGuiApplicationPrivate::platformTheme(); + if (theme == nullptr) + return {}; + + auto &cache = *iconTypeCache(); + auto it = cache.find(type); + if (it == cache.end()) { + const auto sp = [&]() -> QPlatformTheme::StandardPixmap { + switch (type) { + case QAbstractFileIconProvider::Computer: + return QPlatformTheme::ComputerIcon; + case QAbstractFileIconProvider::Desktop: + return QPlatformTheme::DesktopIcon; + case QAbstractFileIconProvider::Trashcan: + return QPlatformTheme::TrashIcon; + case QAbstractFileIconProvider::Network: + return QPlatformTheme::DriveNetIcon; + case QAbstractFileIconProvider::Drive: + return QPlatformTheme::DriveHDIcon; + case QAbstractFileIconProvider::Folder: + return QPlatformTheme::DirIcon; + case QAbstractFileIconProvider::File: + break; + // no default on purpose; we want warnings when the type enum is extended + } + return QPlatformTheme::FileIcon; + }(); + + const auto sizesHint = theme->themeHint(QPlatformTheme::IconPixmapSizes); + auto sizes = sizesHint.value<QList<QSize>>(); + if (sizes.isEmpty()) + sizes.append({64, 64}); + + QIcon icon; + for (const auto &size : sizes) + icon.addPixmap(theme->standardPixmap(sp, size)); + it = cache.insert(type, icon); + } + return it.value(); +} + +QIcon QAbstractFileIconProviderPrivate::getIconThemeIcon(QAbstractFileIconProvider::IconType type) const +{ + switch (type) { + case QAbstractFileIconProvider::Computer: + return QIcon::fromTheme("computer"_L1); + case QAbstractFileIconProvider::Desktop: + return QIcon::fromTheme("user-desktop"_L1); + case QAbstractFileIconProvider::Trashcan: + return QIcon::fromTheme("user-trash"_L1); + case QAbstractFileIconProvider::Network: + return QIcon::fromTheme("network-workgroup"_L1); + case QAbstractFileIconProvider::Drive: + return QIcon::fromTheme("drive-harddisk"_L1); + case QAbstractFileIconProvider::Folder: + return QIcon::fromTheme("folder"_L1); + case QAbstractFileIconProvider::File: + return QIcon::fromTheme("text-x-generic"_L1); + // no default on purpose; we want warnings when the type enum is extended + } + return QIcon::fromTheme("text-x-generic"_L1); +} + +static inline QPlatformTheme::IconOptions toThemeIconOptions(QAbstractFileIconProvider::Options options) +{ + QPlatformTheme::IconOptions result; + if (options.testFlag(QAbstractFileIconProvider::DontUseCustomDirectoryIcons)) + result |= QPlatformTheme::DontUseCustomDirectoryIcons; + return result; +} + +QIcon QAbstractFileIconProviderPrivate::getPlatformThemeIcon(const QFileInfo &info) const +{ + if (auto theme = QGuiApplicationPrivate::platformTheme()) + return theme->fileIcon(info, toThemeIconOptions(options)); + return {}; +} + +QIcon QAbstractFileIconProviderPrivate::getIconThemeIcon(const QFileInfo &info) const +{ + if (info.isRoot()) + return getIconThemeIcon(QAbstractFileIconProvider::Drive); + if (info.isDir()) + return getIconThemeIcon(QAbstractFileIconProvider::Folder); +#if QT_CONFIG(mimetype) + return QIcon::fromTheme(mimeDatabase.mimeTypeForFile(info).iconName()); +#else + return QIcon::fromTheme("text-x-generic"_L1); +#endif +} + /*! \class QAbstractFileIconProvider @@ -139,25 +210,9 @@ QAbstractFileIconProvider::Options QAbstractFileIconProvider::options() const QIcon QAbstractFileIconProvider::icon(IconType type) const { - Q_UNUSED(type); - switch (type) { - case Computer: - return QIcon::fromTheme(QLatin1String("computer")); - case Desktop: - return QIcon::fromTheme(QLatin1String("user-desktop")); - case Trashcan: - return QIcon::fromTheme(QLatin1String("user-trash")); - case Network: - return QIcon::fromTheme(QLatin1String("network-workgroup")); - case Drive: - return QIcon::fromTheme(QLatin1String("drive-harddisk")); - case Folder: - return QIcon::fromTheme(QLatin1String("folder")); - case File: - return QIcon::fromTheme(QLatin1String("text-x-generic")); - // no default on purpose; we want warnings when the type enum is extended - } - return QIcon::fromTheme(QLatin1String("text-x-generic")); + Q_D(const QAbstractFileIconProvider); + const QIcon result = d->getIconThemeIcon(type); + return result.isNull() ? d->getPlatformThemeIcon(type) : result; } /*! @@ -170,25 +225,22 @@ QIcon QAbstractFileIconProvider::icon(IconType type) const QIcon QAbstractFileIconProvider::icon(const QFileInfo &info) const { Q_D(const QAbstractFileIconProvider); - if (info.isRoot()) - return icon(Drive); - if (info.isDir()) - return icon(Folder); - return QIcon::fromTheme(d->mimeDatabase.mimeTypeForFile(info).iconName()); + const QIcon result = d->getIconThemeIcon(info); + return result.isNull() ? d->getPlatformThemeIcon(info) : result; } -/*! - Returns the type of the file described by \a info. -*/ -QString QAbstractFileIconProvider::type(const QFileInfo &info) const +QString QAbstractFileIconProviderPrivate::getFileType(const QFileInfo &info) { - Q_D(const QAbstractFileIconProvider); if (QFileSystemEntry::isRootPath(info.absoluteFilePath())) return QGuiApplication::translate("QAbstractFileIconProvider", "Drive"); if (info.isFile()) { - const QMimeType mimeType = d->mimeDatabase.mimeTypeForFile(info); +#if QT_CONFIG(mimetype) + const QMimeType mimeType = QMimeDatabase().mimeTypeForFile(info); return mimeType.comment().isEmpty() ? mimeType.name() : mimeType.comment(); +#else + return QGuiApplication::translate("QAbstractFileIconProvider", "File"); +#endif } if (info.isDir()) @@ -216,4 +268,13 @@ QString QAbstractFileIconProvider::type(const QFileInfo &info) const return QGuiApplication::translate("QAbstractFileIconProvider", "Unknown"); } +/*! + Returns the type of the file described by \a info. +*/ + +QString QAbstractFileIconProvider::type(const QFileInfo &info) const +{ + return QAbstractFileIconProviderPrivate::getFileType(info); +} + QT_END_NAMESPACE |