From 349de159c96c4b1e20a95f33aa17319c7d491247 Mon Sep 17 00:00:00 2001 From: Eike Ziller Date: Fri, 15 Nov 2019 14:12:26 +0100 Subject: [PATCH] FileIconProvider: Load icons and create overlay lazily If the icon is registered via file path, not the icon directly, we can delay loading the icon and creating the overlay to until it is actually needed. Change-Id: Icfdc30ac0b717ff566a1064e4791e4bb23814958 Reviewed-by: hjk --- src/plugins/coreplugin/fileiconprovider.cpp | 77 +++++++++++++-------- src/plugins/cppeditor/cppeditorplugin.cpp | 12 ++-- 2 files changed, 55 insertions(+), 34 deletions(-) diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/plugins/coreplugin/fileiconprovider.cpp index fb13455641d..ea529787842 100644 --- a/src/plugins/coreplugin/fileiconprovider.cpp +++ b/src/plugins/coreplugin/fileiconprovider.cpp @@ -27,7 +27,9 @@ #include #include +#include #include +#include #include #include @@ -56,14 +58,29 @@ using namespace Utils; retrieve icons via the icon() function. */ -// Cache icons in a list of pairs suffix/icon which should be faster than -// hashes for small lists. +using Item = Utils::variant; // icon or filename for the icon namespace Core { namespace FileIconProvider { enum { debug = 0 }; +static Utils::optional getIcon(QHash &cache, const QString &key) +{ + auto it = cache.constFind(key); + if (it == cache.constEnd()) + return {}; + if (const QIcon *icon = Utils::get_if(&*it)) + return *icon; + // need to create icon from file name first + const QString *fileName = Utils::get_if(&*it); + QTC_ASSERT(fileName, return {}); + const QIcon icon = QIcon( + FileIconProvider::overlayIcon(QStyle::SP_FileIcon, QIcon(*fileName), QSize(16, 16))); + cache.insert(key, icon); + return icon; +} + class FileIconProviderImplementation : public QFileIconProvider { public: @@ -73,35 +90,39 @@ public: QIcon icon(const QFileInfo &info) const override; using QFileIconProvider::icon; - void registerIconOverlayForFilename(const QIcon &icon, const QString &filename) + void registerIconOverlayForFilename(const QString &iconFilePath, const QString &filename) { - QTC_ASSERT(!icon.isNull() && !filename.isEmpty(), return); - - const QPixmap fileIconPixmap = FileIconProvider::overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16)); - m_filenameCache.insert(filename, fileIconPixmap); + m_filenameCache.insert(filename, iconFilePath); } - void registerIconOverlayForSuffix(const QIcon &icon, const QString &suffix) + void registerIconOverlayForSuffix(const QString &iconFilePath, const QString &suffix) { - if (debug) - qDebug() << "FileIconProvider::registerIconOverlayForSuffix" << suffix; - - QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return); - - const QPixmap fileIconPixmap = FileIconProvider::overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16)); - // replace old icon, if it exists - m_suffixCache.insert(suffix, fileIconPixmap); + m_suffixCache.insert(suffix, iconFilePath); } void registerIconOverlayForMimeType(const QIcon &icon, const Utils::MimeType &mimeType) + { + const QStringList suffixes = mimeType.suffixes(); + for (const QString &suffix : suffixes) { + QTC_ASSERT(!icon.isNull() && !suffix.isEmpty(), return ); + + const QPixmap fileIconPixmap = FileIconProvider::overlayIcon(QStyle::SP_FileIcon, + icon, + QSize(16, 16)); + // replace old icon, if it exists + m_suffixCache.insert(suffix, fileIconPixmap); + } + } + + void registerIconOverlayForMimeType(const QString &iconFilePath, const Utils::MimeType &mimeType) { foreach (const QString &suffix, mimeType.suffixes()) - registerIconOverlayForSuffix(icon, suffix); + registerIconOverlayForSuffix(iconFilePath, suffix); } // Mapping of file suffix to icon. - mutable QHash m_suffixCache; - QHash m_filenameCache; + mutable QHash m_suffixCache; + mutable QHash m_filenameCache; }; FileIconProviderImplementation *instance() @@ -123,15 +144,15 @@ QIcon FileIconProviderImplementation::icon(const QFileInfo &fileInfo) const bool isDir = fileInfo.isDir(); const QString filename = !isDir ? fileInfo.fileName() : QString(); if (!filename.isEmpty()) { - auto it = m_filenameCache.constFind(filename); - if (it != m_filenameCache.constEnd()) - return it.value(); + const Utils::optional icon = getIcon(m_filenameCache, filename); + if (icon) + return *icon; } const QString suffix = !isDir ? fileInfo.suffix() : QString(); if (!suffix.isEmpty()) { - auto it = m_suffixCache.constFind(suffix); - if (it != m_suffixCache.constEnd()) - return it.value(); + const Utils::optional icon = getIcon(m_suffixCache, suffix); + if (icon) + return *icon; } // Get icon from OS (and cache it based on suffix!) @@ -192,7 +213,7 @@ QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlay, const */ void registerIconOverlayForSuffix(const QString &path, const QString &suffix) { - instance()->registerIconOverlayForSuffix(QIcon(path), suffix); + instance()->registerIconOverlayForSuffix(path, suffix); } /*! @@ -208,12 +229,12 @@ void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType) */ void registerIconOverlayForMimeType(const QString &path, const QString &mimeType) { - instance()->registerIconOverlayForMimeType(QIcon(path), Utils::mimeTypeForName(mimeType)); + instance()->registerIconOverlayForMimeType(path, Utils::mimeTypeForName(mimeType)); } void registerIconOverlayForFilename(const QString &path, const QString &filename) { - instance()->registerIconOverlayForFilename(QIcon(path), filename); + instance()->registerIconOverlayForFilename(path, filename); } // Return a standard directory icon with the specified overlay: diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp index bb732724463..bb86ee5be78 100644 --- a/src/plugins/cppeditor/cppeditorplugin.cpp +++ b/src/plugins/cppeditor/cppeditorplugin.cpp @@ -296,14 +296,14 @@ void CppEditorPlugin::extensionsInitialized() if (!HostOsInfo::isMacHost() && !HostOsInfo::isWindowsHost()) { FileIconProvider::registerIconOverlayForMimeType( - QIcon(creatorTheme()->imageFile(Theme::IconOverlayCppSource, QLatin1String(":/cppeditor/images/qt_cpp.png"))), - CppTools::Constants::CPP_SOURCE_MIMETYPE); + creatorTheme()->imageFile(Theme::IconOverlayCppSource, ":/cppeditor/images/qt_cpp.png"), + CppTools::Constants::CPP_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType( - QIcon(creatorTheme()->imageFile(Theme::IconOverlayCSource, QLatin1String(":/cppeditor/images/qt_c.png"))), - CppTools::Constants::C_SOURCE_MIMETYPE); + creatorTheme()->imageFile(Theme::IconOverlayCSource, ":/cppeditor/images/qt_c.png"), + CppTools::Constants::C_SOURCE_MIMETYPE); FileIconProvider::registerIconOverlayForMimeType( - QIcon(creatorTheme()->imageFile(Theme::IconOverlayCppHeader, QLatin1String(":/cppeditor/images/qt_h.png"))), - CppTools::Constants::CPP_HEADER_MIMETYPE); + creatorTheme()->imageFile(Theme::IconOverlayCppHeader, ":/cppeditor/images/qt_h.png"), + CppTools::Constants::CPP_HEADER_MIMETYPE); } }