summaryrefslogtreecommitdiffstats
path: root/src/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'src/widgets')
-rw-r--r--src/widgets/itemviews/qfileiconprovider.cpp136
-rw-r--r--src/widgets/itemviews/qfileiconprovider_p.h2
2 files changed, 89 insertions, 49 deletions
diff --git a/src/widgets/itemviews/qfileiconprovider.cpp b/src/widgets/itemviews/qfileiconprovider.cpp
index d1bd0e657e..740bd853b7 100644
--- a/src/widgets/itemviews/qfileiconprovider.cpp
+++ b/src/widgets/itemviews/qfileiconprovider.cpp
@@ -39,6 +39,7 @@
#include <qpixmapcache.h>
#include <private/qfunctions_p.h>
#include <private/qguiapplication_p.h>
+#include <private/qicon_p.h>
#include <qpa/qplatformintegration.h>
#include <qpa/qplatformservices.h>
#include <qpa/qplatformtheme.h>
@@ -57,6 +58,88 @@
QT_BEGIN_NAMESPACE
+static bool isCacheable(const QFileInfo &fi);
+
+class QFileIconEngine : public QPixmapIconEngine
+{
+public:
+ QFileIconEngine(const QFileIconProvider *fip, const QFileInfo &info)
+ : QPixmapIconEngine(), m_fileIconProvider(fip), m_fileInfo(info)
+ { }
+
+ QPixmap pixmap(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(mode);
+ Q_UNUSED(state);
+ QPixmap pixmap;
+
+ if (!size.isValid())
+ return pixmap;
+
+ const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
+ if (!theme)
+ return pixmap;
+
+ const QString &keyBase = QLatin1String("qt_.") + m_fileInfo.suffix().toUpper();
+
+ bool cacheable = isCacheable(m_fileInfo);
+ if (cacheable) {
+ QPixmapCache::find(keyBase + QString::number(size.width()), pixmap);
+ if (!pixmap.isNull())
+ return pixmap;
+ }
+
+ QPlatformTheme::IconOptions iconOptions;
+ if (m_fileIconProvider->options() & QFileIconProvider::DontUseCustomDirectoryIcons)
+ iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons;
+
+ pixmap = theme->fileIconPixmap(m_fileInfo, size, iconOptions);
+ if (!pixmap.isNull()) {
+ if (cacheable)
+ QPixmapCache::insert(keyBase + QString::number(size.width()), pixmap);
+ }
+
+ return pixmap;
+ }
+
+ QList<QSize> availableSizes(QIcon::Mode mode = QIcon::Normal, QIcon::State state = QIcon::Off) const Q_DECL_OVERRIDE
+ {
+ Q_UNUSED(mode);
+ Q_UNUSED(state);
+ static QList<QSize> sizes;
+ static QPlatformTheme *theme = 0;
+ if (!theme) {
+ theme = QGuiApplicationPrivate::platformTheme();
+ if (!theme)
+ return sizes;
+
+ QList<int> themeSizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >();
+ if (themeSizes.isEmpty())
+ return sizes;
+
+ foreach (int size, themeSizes)
+ sizes << QSize(size, size);
+ }
+ return sizes;
+ }
+
+ QSize actualSize(const QSize &size, QIcon::Mode mode, QIcon::State state) Q_DECL_OVERRIDE
+ {
+ const QList<QSize> &sizes = availableSizes(mode, state);
+ foreach (const QSize &availableSize, sizes) {
+ if (availableSize.width() >= size.width())
+ return availableSize;
+ }
+
+ return sizes.last();
+ }
+
+private:
+ const QFileIconProvider *m_fileIconProvider;
+ QFileInfo m_fileInfo;
+};
+
+
/*!
\class QFileIconProvider
@@ -86,8 +169,8 @@ QT_BEGIN_NAMESPACE
cause a big performance impact over network or removable drives.
*/
-QFileIconProviderPrivate::QFileIconProviderPrivate() :
- homePath(QDir::home().absolutePath())
+QFileIconProviderPrivate::QFileIconProviderPrivate(QFileIconProvider *q) :
+ q_ptr(q), homePath(QDir::home().absolutePath())
{
}
@@ -153,7 +236,7 @@ QIcon QFileIconProviderPrivate::getIcon(QStyle::StandardPixmap name) const
*/
QFileIconProvider::QFileIconProvider()
- : d_ptr(new QFileIconProviderPrivate)
+ : d_ptr(new QFileIconProviderPrivate(this))
{
}
@@ -238,53 +321,10 @@ static bool isCacheable(const QFileInfo &fi)
QIcon QFileIconProviderPrivate::getIcon(const QFileInfo &fi) const
{
- QIcon retIcon;
- const QPlatformTheme *theme = QGuiApplicationPrivate::platformTheme();
- if (!theme)
- return retIcon;
-
- QList<int> sizes = theme->themeHint(QPlatformTheme::IconPixmapSizes).value<QList<int> >();
- if (sizes.isEmpty())
- return retIcon;
-
- const QString keyBase = QLatin1String("qt_.") + fi.suffix().toUpper();
-
- bool cacheable = isCacheable(fi);
- if (cacheable) {
- QPixmap pixmap;
- QPixmapCache::find(keyBase + QString::number(sizes.at(0)), pixmap);
- if (!pixmap.isNull()) {
- bool iconIsComplete = true;
- retIcon.addPixmap(pixmap);
- for (int i = 1; i < sizes.count(); i++)
- if (QPixmapCache::find(keyBase + QString::number(sizes.at(i)), pixmap)) {
- retIcon.addPixmap(pixmap);
- } else {
- iconIsComplete = false;
- break;
- }
- if (iconIsComplete)
- return retIcon;
- }
- }
-
- QPlatformTheme::IconOptions iconOptions;
- if (options & QFileIconProvider::DontUseCustomDirectoryIcons)
- iconOptions |= QPlatformTheme::DontUseCustomDirectoryIcons;
-
- Q_FOREACH (int size, sizes) {
- QPixmap pixmap = theme->fileIconPixmap(fi, QSizeF(size, size), iconOptions);
- if (!pixmap.isNull()) {
- retIcon.addPixmap(pixmap);
- if (cacheable)
- QPixmapCache::insert(keyBase + QString::number(size), pixmap);
- }
- }
-
- return retIcon;
+ Q_Q(const QFileIconProvider);
+ return QIcon(new QFileIconEngine(q, fi));
}
-
/*!
Returns an icon for the file described by \a info.
*/
diff --git a/src/widgets/itemviews/qfileiconprovider_p.h b/src/widgets/itemviews/qfileiconprovider_p.h
index 213535616c..a1fb4acbea 100644
--- a/src/widgets/itemviews/qfileiconprovider_p.h
+++ b/src/widgets/itemviews/qfileiconprovider_p.h
@@ -60,7 +60,7 @@ class QFileIconProviderPrivate
Q_DECLARE_PUBLIC(QFileIconProvider)
public:
- QFileIconProviderPrivate();
+ QFileIconProviderPrivate(QFileIconProvider *q);
QIcon getIcon(QStyle::StandardPixmap name) const;
QIcon getIcon(const QFileInfo &fi) const;