forked from qt-creator/qt-creator
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 <hjk@qt.io>
This commit is contained in:
@@ -27,7 +27,9 @@
|
||||
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/mimetypes/mimedatabase.h>
|
||||
#include <utils/optional.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/variant.h>
|
||||
|
||||
#include <QApplication>
|
||||
#include <QStyle>
|
||||
@@ -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<QIcon, QString>; // icon or filename for the icon
|
||||
|
||||
namespace Core {
|
||||
namespace FileIconProvider {
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
static Utils::optional<QIcon> getIcon(QHash<QString, Item> &cache, const QString &key)
|
||||
{
|
||||
auto it = cache.constFind(key);
|
||||
if (it == cache.constEnd())
|
||||
return {};
|
||||
if (const QIcon *icon = Utils::get_if<QIcon>(&*it))
|
||||
return *icon;
|
||||
// need to create icon from file name first
|
||||
const QString *fileName = Utils::get_if<QString>(&*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<QString, QIcon> m_suffixCache;
|
||||
QHash<QString, QIcon> m_filenameCache;
|
||||
mutable QHash<QString, Item> m_suffixCache;
|
||||
mutable QHash<QString, Item> 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<QIcon> 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<QIcon> 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:
|
||||
|
@@ -296,13 +296,13 @@ void CppEditorPlugin::extensionsInitialized()
|
||||
|
||||
if (!HostOsInfo::isMacHost() && !HostOsInfo::isWindowsHost()) {
|
||||
FileIconProvider::registerIconOverlayForMimeType(
|
||||
QIcon(creatorTheme()->imageFile(Theme::IconOverlayCppSource, QLatin1String(":/cppeditor/images/qt_cpp.png"))),
|
||||
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"))),
|
||||
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"))),
|
||||
creatorTheme()->imageFile(Theme::IconOverlayCppHeader, ":/cppeditor/images/qt_h.png"),
|
||||
CppTools::Constants::CPP_HEADER_MIMETYPE);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user