From 0bd915c34cf7097af3f8fcc1d981a16c282773b8 Mon Sep 17 00:00:00 2001 From: Charles Kerr Date: Wed, 2 Sep 2020 19:28:36 -0500 Subject: [PATCH] fixup! refactor: speed up FaviconCache::add() again. (#1402) --- qt/FileTreeItem.cc | 5 +- qt/IconCache.cc | 25 ++++---- qt/IconCache.h | 2 +- qt/Torrent.cc | 4 +- qt/Utils.cc | 145 --------------------------------------------- 5 files changed, 21 insertions(+), 160 deletions(-) diff --git a/qt/FileTreeItem.cc b/qt/FileTreeItem.cc index bd842236e..f5fe658f3 100644 --- a/qt/FileTreeItem.cc +++ b/qt/FileTreeItem.cc @@ -171,7 +171,10 @@ QVariant FileTreeItem::data(int column, int role) const } else { - value = IconCache::get().guessMimeIcon(name()); + auto& icon_cache = IconCache::get(); + value = childCount() > 0 ? + icon_cache.folderIcon() : + icon_cache.guessMimeIcon(name(), icon_cache.fileIcon()); } } diff --git a/qt/IconCache.cc b/qt/IconCache.cc index d61bdb3fb..1ab2c935b 100644 --- a/qt/IconCache.cc +++ b/qt/IconCache.cc @@ -41,16 +41,16 @@ IconCache& IconCache::get() IconCache::IconCache() : 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; +#ifdef _WIN32 + if (!filename.isEmpty()) { QFileInfo const file_info(filename); @@ -60,13 +60,18 @@ QIcon IconCache::guessMimeIcon(QString const& filename) const addAssociatedFileIcon(file_info, SHGFI_LARGEICON, icon); } - return icon; - #else - return getMimeIcon(filename); + icon = getMimeIcon(filename, fallback); #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 { - // 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()) { for (auto const& type : QMimeDatabase().allMimeTypes()) @@ -125,7 +128,7 @@ QIcon IconCache::getMimeIcon(QString const& filename) const auto const ext = QFileInfo(filename).suffix(); if (suffixes_.count(ext) == 0) { - return folder_icon_; + return {}; } QIcon& icon = icon_cache_[ext]; @@ -145,7 +148,7 @@ QIcon IconCache::getMimeIcon(QString const& filename) const if (icon.isNull()) { - icon = file_icon_; + icon = {}; } } diff --git a/qt/IconCache.h b/qt/IconCache.h index 11cfe5739..f17e11908 100644 --- a/qt/IconCache.h +++ b/qt/IconCache.h @@ -29,7 +29,7 @@ public: QIcon folderIcon() const { return folder_icon_; } QIcon fileIcon() const { return file_icon_; } - QIcon guessMimeIcon(QString const& filename) const; + QIcon guessMimeIcon(QString const& filename, QIcon fallback = {}) const; protected: IconCache(); diff --git a/qt/Torrent.cc b/qt/Torrent.cc index aeec537a8..68fdbfe57 100644 --- a/qt/Torrent.cc +++ b/qt/Torrent.cc @@ -173,11 +173,11 @@ void Torrent::updateMimeIcon() } 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 { - icon = icon_cache.guessMimeIcon(name()); + icon = icon_cache.guessMimeIcon(name(), icon_cache.folderIcon()); } icon_ = icon; diff --git a/qt/Utils.cc b/qt/Utils.cc index ae953ad49..5e9e3b8d1 100644 --- a/qt/Utils.cc +++ b/qt/Utils.cc @@ -52,153 +52,8 @@ bool isSlashChar(QChar const& c) 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 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 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 -#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) { QVariant const variant = index.data(Qt::DecorationRole);