diff options
Diffstat (limited to 'src/gui/image')
-rw-r--r-- | src/gui/image/qabstractfileiconprovider.cpp | 128 | ||||
-rw-r--r-- | src/gui/image/qabstractfileiconprovider_p.h | 7 |
2 files changed, 111 insertions, 24 deletions
diff --git a/src/gui/image/qabstractfileiconprovider.cpp b/src/gui/image/qabstractfileiconprovider.cpp index 51638f69d8..dbf27d9360 100644 --- a/src/gui/image/qabstractfileiconprovider.cpp +++ b/src/gui/image/qabstractfileiconprovider.cpp @@ -40,6 +40,8 @@ #include "qabstractfileiconprovider.h" #include <qguiapplication.h> +#include <private/qguiapplication_p.h> +#include <qpa/qplatformtheme.h> #include <qicon.h> #include <qmimedatabase.h> @@ -55,6 +57,103 @@ QAbstractFileIconProviderPrivate::QAbstractFileIconProviderPrivate(QAbstractFile 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(QLatin1String("computer")); + case QAbstractFileIconProvider::Desktop: + return QIcon::fromTheme(QLatin1String("user-desktop")); + case QAbstractFileIconProvider::Trashcan: + return QIcon::fromTheme(QLatin1String("user-trash")); + case QAbstractFileIconProvider::Network: + return QIcon::fromTheme(QLatin1String("network-workgroup")); + case QAbstractFileIconProvider::Drive: + return QIcon::fromTheme(QLatin1String("drive-harddisk")); + case QAbstractFileIconProvider::Folder: + return QIcon::fromTheme(QLatin1String("folder")); + case QAbstractFileIconProvider::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")); +} + +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); + return QIcon::fromTheme(mimeDatabase.mimeTypeForFile(info).iconName()); +} + /*! \class QAbstractFileIconProvider @@ -139,25 +238,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,11 +253,8 @@ 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; } /*! diff --git a/src/gui/image/qabstractfileiconprovider_p.h b/src/gui/image/qabstractfileiconprovider_p.h index 53ad4826eb..37646f77e6 100644 --- a/src/gui/image/qabstractfileiconprovider_p.h +++ b/src/gui/image/qabstractfileiconprovider_p.h @@ -65,6 +65,13 @@ public: QAbstractFileIconProviderPrivate(QAbstractFileIconProvider *q); virtual ~QAbstractFileIconProviderPrivate(); + QIcon getPlatformThemeIcon(QAbstractFileIconProvider::IconType type) const; + QIcon getIconThemeIcon(QAbstractFileIconProvider::IconType type) const; + QIcon getPlatformThemeIcon(const QFileInfo &info) const; + QIcon getIconThemeIcon(const QFileInfo &info) const; + + static void clearIconTypeCache(); + QAbstractFileIconProvider *q_ptr = nullptr; QAbstractFileIconProvider::Options options = {}; |