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/hostosinfo.h>
|
||||||
#include <utils/mimetypes/mimedatabase.h>
|
#include <utils/mimetypes/mimedatabase.h>
|
||||||
|
#include <utils/optional.h>
|
||||||
#include <utils/qtcassert.h>
|
#include <utils/qtcassert.h>
|
||||||
|
#include <utils/variant.h>
|
||||||
|
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
#include <QStyle>
|
#include <QStyle>
|
||||||
@@ -56,14 +58,29 @@ using namespace Utils;
|
|||||||
retrieve icons via the icon() function.
|
retrieve icons via the icon() function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// Cache icons in a list of pairs suffix/icon which should be faster than
|
using Item = Utils::variant<QIcon, QString>; // icon or filename for the icon
|
||||||
// hashes for small lists.
|
|
||||||
|
|
||||||
namespace Core {
|
namespace Core {
|
||||||
namespace FileIconProvider {
|
namespace FileIconProvider {
|
||||||
|
|
||||||
enum { debug = 0 };
|
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
|
class FileIconProviderImplementation : public QFileIconProvider
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -73,35 +90,39 @@ public:
|
|||||||
QIcon icon(const QFileInfo &info) const override;
|
QIcon icon(const QFileInfo &info) const override;
|
||||||
using QFileIconProvider::icon;
|
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);
|
m_filenameCache.insert(filename, iconFilePath);
|
||||||
|
|
||||||
const QPixmap fileIconPixmap = FileIconProvider::overlayIcon(QStyle::SP_FileIcon, icon, QSize(16, 16));
|
|
||||||
m_filenameCache.insert(filename, fileIconPixmap);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerIconOverlayForSuffix(const QIcon &icon, const QString &suffix)
|
void registerIconOverlayForSuffix(const QString &iconFilePath, const QString &suffix)
|
||||||
{
|
{
|
||||||
if (debug)
|
m_suffixCache.insert(suffix, iconFilePath);
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void registerIconOverlayForMimeType(const QIcon &icon, const Utils::MimeType &mimeType)
|
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())
|
foreach (const QString &suffix, mimeType.suffixes())
|
||||||
registerIconOverlayForSuffix(icon, suffix);
|
registerIconOverlayForSuffix(iconFilePath, suffix);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mapping of file suffix to icon.
|
// Mapping of file suffix to icon.
|
||||||
mutable QHash<QString, QIcon> m_suffixCache;
|
mutable QHash<QString, Item> m_suffixCache;
|
||||||
QHash<QString, QIcon> m_filenameCache;
|
mutable QHash<QString, Item> m_filenameCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
FileIconProviderImplementation *instance()
|
FileIconProviderImplementation *instance()
|
||||||
@@ -123,15 +144,15 @@ QIcon FileIconProviderImplementation::icon(const QFileInfo &fileInfo) const
|
|||||||
bool isDir = fileInfo.isDir();
|
bool isDir = fileInfo.isDir();
|
||||||
const QString filename = !isDir ? fileInfo.fileName() : QString();
|
const QString filename = !isDir ? fileInfo.fileName() : QString();
|
||||||
if (!filename.isEmpty()) {
|
if (!filename.isEmpty()) {
|
||||||
auto it = m_filenameCache.constFind(filename);
|
const Utils::optional<QIcon> icon = getIcon(m_filenameCache, filename);
|
||||||
if (it != m_filenameCache.constEnd())
|
if (icon)
|
||||||
return it.value();
|
return *icon;
|
||||||
}
|
}
|
||||||
const QString suffix = !isDir ? fileInfo.suffix() : QString();
|
const QString suffix = !isDir ? fileInfo.suffix() : QString();
|
||||||
if (!suffix.isEmpty()) {
|
if (!suffix.isEmpty()) {
|
||||||
auto it = m_suffixCache.constFind(suffix);
|
const Utils::optional<QIcon> icon = getIcon(m_suffixCache, suffix);
|
||||||
if (it != m_suffixCache.constEnd())
|
if (icon)
|
||||||
return it.value();
|
return *icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get icon from OS (and cache it based on suffix!)
|
// 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)
|
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)
|
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)
|
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:
|
// Return a standard directory icon with the specified overlay:
|
||||||
|
@@ -296,14 +296,14 @@ void CppEditorPlugin::extensionsInitialized()
|
|||||||
|
|
||||||
if (!HostOsInfo::isMacHost() && !HostOsInfo::isWindowsHost()) {
|
if (!HostOsInfo::isMacHost() && !HostOsInfo::isWindowsHost()) {
|
||||||
FileIconProvider::registerIconOverlayForMimeType(
|
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);
|
CppTools::Constants::CPP_SOURCE_MIMETYPE);
|
||||||
FileIconProvider::registerIconOverlayForMimeType(
|
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);
|
CppTools::Constants::C_SOURCE_MIMETYPE);
|
||||||
FileIconProvider::registerIconOverlayForMimeType(
|
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);
|
CppTools::Constants::CPP_HEADER_MIMETYPE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user