changeset 33094:dbf49a4f50da stable

GUI: Cache file icons for file browser (bug #65312). * files-dock-widget.h (class files_dock_widget): New member variable "m_file_icon_provider". * files-dock-widget.cc (cache_file_icon_provider): New local class inheriting from QFileIconProvider to cache icons for Qt in a std::map. * files-dock-widget.cc (files_dock_widget::files_dock_widget): Initialize "m_file_icon_provider" and "m_file_system_model" in constructor.
author Markus Mützel <markus.muetzel@gmx.de>
date Fri, 16 Feb 2024 18:01:09 +0100
parents 6ed312edd0d4
children aabaf97c66ab 55c8c338aaeb
files libgui/src/files-dock-widget.cc libgui/src/files-dock-widget.h
diffstat 2 files changed, 59 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libgui/src/files-dock-widget.cc	Mon Feb 26 23:28:09 2024 -0500
+++ b/libgui/src/files-dock-widget.cc	Fri Feb 16 18:01:09 2024 +0100
@@ -27,6 +27,8 @@
 #  include "config.h"
 #endif
 
+#include <map>
+
 #include <QApplication>
 #include <QClipboard>
 #include <QCompleter>
@@ -39,6 +41,8 @@
 #include <QLineEdit>
 #include <QMenu>
 #include <QMessageBox>
+#include <QMimeDatabase>
+#include <QMimeType>
 #include <QProcess>
 #include <QSizePolicy>
 #include <QStyledItemDelegate>
@@ -177,6 +181,56 @@
   }
 };
 
+class cache_file_icon_provider : public QFileIconProvider
+{
+public:
+  cache_file_icon_provider ()
+  {
+    m_null_icon = QIcon ();
+    m_file_icon = m_file_icon_provider.icon (QFileIconProvider::File);
+    m_folder_icon = m_file_icon_provider.icon (QFileIconProvider::Folder);
+  }
+
+  QIcon icon (IconType ict) const
+  {
+    if (ict == QFileIconProvider::File)
+      return m_file_icon;
+    else if (ict == QFileIconProvider::Folder)
+      return m_folder_icon;
+    else
+      return m_null_icon;
+  }
+  
+  QIcon icon (const QFileInfo &fi) const
+  {
+    static bool no_platform_theme = QIcon::themeName ().isEmpty ();
+
+    if (no_platform_theme)
+      return m_file_icon_provider.icon (fi);
+
+    QMimeType mime_type = m_db.mimeTypeForFile (fi.absoluteFilePath ());
+    QString icon_name = mime_type.iconName ();
+    auto mime_type_iter = m_icon_cache.find (icon_name);
+    if (mime_type_iter != m_icon_cache.end ())
+      return mime_type_iter->second;
+
+    QIcon icon = QIcon::fromTheme (icon_name);
+    m_icon_cache.insert ({icon_name, icon});
+    return icon;
+  }
+
+private:
+  QIcon m_null_icon;
+  QIcon m_file_icon;
+  QIcon m_folder_icon;
+
+  QFileIconProvider m_file_icon_provider;
+  QMimeDatabase m_db;
+  static std::map<QString, QIcon> m_icon_cache;
+};
+
+std::map<QString, QIcon> cache_file_icon_provider::m_icon_cache;
+
 files_dock_widget::files_dock_widget (QWidget *p)
   : octave_dock_widget ("FilesDockWidget", p)
 {
@@ -315,6 +369,9 @@
   QModelIndex rootPathIndex
     = m_file_system_model->setRootPath (startup_dir.absolutePath ());
 
+  m_file_icon_provider = new cache_file_icon_provider ();
+  m_file_system_model->setIconProvider (m_file_icon_provider);
+
   // Attach the model to the QTreeView and set the root index
   m_file_tree_view = new FileTreeViewer (container);
   m_file_tree_view->setSelectionMode (QAbstractItemView::ExtendedSelection);
--- a/libgui/src/files-dock-widget.h	Mon Feb 26 23:28:09 2024 -0500
+++ b/libgui/src/files-dock-widget.h	Fri Feb 16 18:01:09 2024 +0100
@@ -29,6 +29,7 @@
 #include <QAction>
 #include <QComboBox>
 #include <QDate>
+#include <QFileIconProvider>
 #include <QFileSystemModel>
 #include <QList>
 #include <QListView>
@@ -210,6 +211,7 @@
   //! The file system model.
 
   QFileSystemModel *m_file_system_model;
+  QFileIconProvider *m_file_icon_provider;
 
   //! The file system view.
   //!@{