fixup! refactor: speed up FaviconCache::add() again. (#1402)
This commit is contained in:
parent
848125d6d8
commit
0bd915c34c
|
@ -171,7 +171,10 @@ QVariant FileTreeItem::data(int column, int role) const
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
value = IconCache::get().guessMimeIcon(name());
|
auto& icon_cache = IconCache::get();
|
||||||
|
value = childCount() > 0 ?
|
||||||
|
icon_cache.folderIcon() :
|
||||||
|
icon_cache.guessMimeIcon(name(), icon_cache.fileIcon());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,16 +41,16 @@ IconCache& IconCache::get()
|
||||||
|
|
||||||
IconCache::IconCache() :
|
IconCache::IconCache() :
|
||||||
folder_icon_(QFileIconProvider().icon(QFileIconProvider::Folder)),
|
folder_icon_(QFileIconProvider().icon(QFileIconProvider::Folder)),
|
||||||
file_icon_(QFileIconProvider().icon(QFileIconProvider::Folder))
|
file_icon_(QFileIconProvider().icon(QFileIconProvider::File))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon IconCache::guessMimeIcon(QString const& filename) const
|
QIcon IconCache::guessMimeIcon(QString const& filename, QIcon fallback) const
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
QIcon icon;
|
QIcon icon;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
if (!filename.isEmpty())
|
if (!filename.isEmpty())
|
||||||
{
|
{
|
||||||
QFileInfo const file_info(filename);
|
QFileInfo const file_info(filename);
|
||||||
|
@ -60,13 +60,18 @@ QIcon IconCache::guessMimeIcon(QString const& filename) const
|
||||||
addAssociatedFileIcon(file_info, SHGFI_LARGEICON, icon);
|
addAssociatedFileIcon(file_info, SHGFI_LARGEICON, icon);
|
||||||
}
|
}
|
||||||
|
|
||||||
return icon;
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return getMimeIcon(filename);
|
icon = getMimeIcon(filename, fallback);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (icon.isNull())
|
||||||
|
{
|
||||||
|
icon = fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return icon;
|
||||||
}
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
|
@ -111,8 +116,6 @@ void IconCache::addAssociatedFileIcon(QFileInfo const& file_info, UINT icon_size
|
||||||
|
|
||||||
QIcon IconCache::getMimeIcon(QString const& filename) const
|
QIcon IconCache::getMimeIcon(QString const& filename) const
|
||||||
{
|
{
|
||||||
// If the suffix doesn't match a mime type, treat it as a folder.
|
|
||||||
// This heuristic is fast and yields good results for torrent names.
|
|
||||||
if (suffixes_.empty())
|
if (suffixes_.empty())
|
||||||
{
|
{
|
||||||
for (auto const& type : QMimeDatabase().allMimeTypes())
|
for (auto const& type : QMimeDatabase().allMimeTypes())
|
||||||
|
@ -125,7 +128,7 @@ QIcon IconCache::getMimeIcon(QString const& filename) const
|
||||||
auto const ext = QFileInfo(filename).suffix();
|
auto const ext = QFileInfo(filename).suffix();
|
||||||
if (suffixes_.count(ext) == 0)
|
if (suffixes_.count(ext) == 0)
|
||||||
{
|
{
|
||||||
return folder_icon_;
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
QIcon& icon = icon_cache_[ext];
|
QIcon& icon = icon_cache_[ext];
|
||||||
|
@ -145,7 +148,7 @@ QIcon IconCache::getMimeIcon(QString const& filename) const
|
||||||
|
|
||||||
if (icon.isNull())
|
if (icon.isNull())
|
||||||
{
|
{
|
||||||
icon = file_icon_;
|
icon = {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ public:
|
||||||
|
|
||||||
QIcon folderIcon() const { return folder_icon_; }
|
QIcon folderIcon() const { return folder_icon_; }
|
||||||
QIcon fileIcon() const { return file_icon_; }
|
QIcon fileIcon() const { return file_icon_; }
|
||||||
QIcon guessMimeIcon(QString const& filename) const;
|
QIcon guessMimeIcon(QString const& filename, QIcon fallback = {}) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
IconCache();
|
IconCache();
|
||||||
|
|
|
@ -173,11 +173,11 @@ void Torrent::updateMimeIcon()
|
||||||
}
|
}
|
||||||
else if (files.size() == 1)
|
else if (files.size() == 1)
|
||||||
{
|
{
|
||||||
icon = icon_cache.guessMimeIcon(files.at(0).filename);
|
icon = icon_cache.guessMimeIcon(files.at(0).filename, icon_cache.fileIcon());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
icon = icon_cache.guessMimeIcon(name());
|
icon = icon_cache.guessMimeIcon(name(), icon_cache.folderIcon());
|
||||||
}
|
}
|
||||||
|
|
||||||
icon_ = icon;
|
icon_ = icon;
|
||||||
|
|
145
qt/Utils.cc
145
qt/Utils.cc
|
@ -52,153 +52,8 @@ bool isSlashChar(QChar const& c)
|
||||||
return c == QLatin1Char('/') || c == QLatin1Char('\\');
|
return c == QLatin1Char('/') || c == QLatin1Char('\\');
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
QIcon folderIcon()
|
|
||||||
{
|
|
||||||
static QIcon icon;
|
|
||||||
if (icon.isNull())
|
|
||||||
{
|
|
||||||
icon = QFileIconProvider().icon(QFileIconProvider::Folder);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon fileIcon()
|
|
||||||
{
|
|
||||||
static QIcon icon;
|
|
||||||
if (icon.isNull())
|
|
||||||
{
|
|
||||||
icon = QFileIconProvider().icon(QFileIconProvider::File);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
void addAssociatedFileIcon(QFileInfo const& file_info, UINT icon_size, QIcon& icon)
|
|
||||||
{
|
|
||||||
QString const pixmap_cache_key = QStringLiteral("tr_file_ext_") + QString::number(icon_size) + QLatin1Char('_') +
|
|
||||||
file_info.suffix();
|
|
||||||
|
|
||||||
QPixmap pixmap;
|
|
||||||
|
|
||||||
if (!QPixmapCache::find(pixmap_cache_key, &pixmap))
|
|
||||||
{
|
|
||||||
auto const filename = file_info.fileName().toStdWString();
|
|
||||||
|
|
||||||
SHFILEINFO shell_file_info;
|
|
||||||
|
|
||||||
if (::SHGetFileInfoW(filename.data(), FILE_ATTRIBUTE_NORMAL, &shell_file_info,
|
|
||||||
sizeof(shell_file_info), SHGFI_ICON | icon_size | SHGFI_USEFILEATTRIBUTES) != 0)
|
|
||||||
{
|
|
||||||
if (shell_file_info.hIcon != nullptr)
|
|
||||||
{
|
|
||||||
pixmap = QtWin::fromHICON(shell_file_info.hIcon);
|
|
||||||
::DestroyIcon(shell_file_info.hIcon);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QPixmapCache::insert(pixmap_cache_key, pixmap);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!pixmap.isNull())
|
|
||||||
{
|
|
||||||
icon.addPixmap(pixmap);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
std::unordered_map<QString, QIcon> icon_cache;
|
|
||||||
|
|
||||||
QIcon getMimeIcon(QString const& filename)
|
|
||||||
{
|
|
||||||
// If the suffix doesn't match a mime type, treat it as a folder.
|
|
||||||
// This heuristic is fast and yields good results for torrent names.
|
|
||||||
static std::unordered_set<QString> suffixes;
|
|
||||||
if (suffixes.empty())
|
|
||||||
{
|
|
||||||
for (auto const& type : QMimeDatabase().allMimeTypes())
|
|
||||||
{
|
|
||||||
auto const tmp = type.suffixes();
|
|
||||||
suffixes.insert(tmp.begin(), tmp.end());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
QString const ext = QFileInfo(filename).suffix();
|
|
||||||
if (suffixes.count(ext) == 0)
|
|
||||||
{
|
|
||||||
return folderIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon& icon = icon_cache[ext];
|
|
||||||
if (icon.isNull()) // cache miss
|
|
||||||
{
|
|
||||||
QMimeDatabase mime_db;
|
|
||||||
QMimeType type = mime_db.mimeTypeForFile(filename, QMimeDatabase::MatchExtension);
|
|
||||||
if (icon.isNull())
|
|
||||||
{
|
|
||||||
icon = QIcon::fromTheme(type.iconName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon.isNull())
|
|
||||||
{
|
|
||||||
icon = QIcon::fromTheme(type.genericIconName());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (icon.isNull())
|
|
||||||
{
|
|
||||||
icon = fileIcon();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
#if 0
|
|
||||||
QIcon Utils::getFolderIcon()
|
|
||||||
{
|
|
||||||
return folderIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon Utils::getFileIcon()
|
|
||||||
{
|
|
||||||
return fileIcon();
|
|
||||||
}
|
|
||||||
|
|
||||||
QIcon Utils::guessMimeIcon(QString const& filename)
|
|
||||||
{
|
|
||||||
#ifdef _WIN32
|
|
||||||
|
|
||||||
QIcon icon;
|
|
||||||
|
|
||||||
if (!filename.isEmpty())
|
|
||||||
{
|
|
||||||
QFileInfo const file_info(filename);
|
|
||||||
|
|
||||||
addAssociatedFileIcon(file_info, SHGFI_SMALLICON, icon);
|
|
||||||
addAssociatedFileIcon(file_info, 0, icon);
|
|
||||||
addAssociatedFileIcon(file_info, SHGFI_LARGEICON, icon);
|
|
||||||
}
|
|
||||||
|
|
||||||
return icon;
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
return getMimeIcon(filename);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QIcon Utils::getIconFromIndex(QModelIndex const& index)
|
QIcon Utils::getIconFromIndex(QModelIndex const& index)
|
||||||
{
|
{
|
||||||
QVariant const variant = index.data(Qt::DecorationRole);
|
QVariant const variant = index.data(Qt::DecorationRole);
|
||||||
|
|
Loading…
Reference in New Issue