QAbstractFileIconProvider: Use platform theme icons

Add code paths to use platform theme icons should icon themes fail.

Task-number: QTBUG-66177
Change-Id: I9554637f5230b1f57faaeef6b2c04cf082271edb
Reviewed-by: Volker Hilsheimer <volker.hilsheimer@qt.io>
This commit is contained in:
Friedemann Kleint 2021-02-11 16:52:18 +01:00
parent c0112c2346
commit 86ebdc07df
4 changed files with 115 additions and 33 deletions

View File

@ -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;
}
/*!

View File

@ -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 = {};

View File

@ -41,6 +41,7 @@
#include "qguiapplication.h"
#include "private/qguiapplication_p.h"
#include "private/qabstractfileiconprovider_p.h"
#include <qpa/qplatformintegrationfactory_p.h>
#include "private/qevent_p.h"
#include "qfont.h"
@ -4130,6 +4131,8 @@ void QGuiApplicationPrivate::notifyThemeChanged()
{
updatePalette();
QAbstractFileIconProviderPrivate::clearIconTypeCache();
if (!(applicationResourceFlags & ApplicationFontExplicitlySet)) {
const auto locker = qt_scoped_lock(applicationFontMutex);
clearFontUnlocked();

View File

@ -172,17 +172,9 @@ QIcon QFileIconProvider::icon(IconType type) const
return QIcon();
}
static inline QPlatformTheme::IconOptions toThemeIconOptions(QFileIconProvider::Options options)
{
QPlatformTheme::IconOptions result;
if (options & QFileIconProvider::DontUseCustomDirectoryIcons)
result |= QPlatformTheme::DontUseCustomDirectoryIcons;
return result;
}
QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
{
return QGuiApplicationPrivate::platformTheme()->fileIcon(fi, toThemeIconOptions(options));
return getPlatformThemeIcon(fi);
}
/*!