From 8082b596aaff7b8c7a4ab272420a731a11e3b476 Mon Sep 17 00:00:00 2001
From: Kubat <mael.martin31@gmail.com>
Date: Mon, 26 Jul 2021 16:24:40 +0200
Subject: [PATCH] UI: Use a custom icon provider for the QFileDialog for cases
 when the system is light themed and Vivy is dark themed and the reverse

---
 src/UI/MainWindow.cc           | 28 +++++++++++++++++++++++++++-
 src/UI/VivyFileIconProvider.cc | 18 ++++++++++++++++++
 src/UI/VivyFileIconProvider.hh | 27 +++++++++++++++++++++++++++
 src/VivyApplication.hh         |  2 ++
 4 files changed, 74 insertions(+), 1 deletion(-)
 create mode 100644 src/UI/VivyFileIconProvider.cc
 create mode 100644 src/UI/VivyFileIconProvider.hh

diff --git a/src/UI/MainWindow.cc b/src/UI/MainWindow.cc
index 2353683b..89ae4396 100644
--- a/src/UI/MainWindow.cc
+++ b/src/UI/MainWindow.cc
@@ -2,6 +2,7 @@
 #include "PropertyModel.hh"
 #include "VivyDocumentView.hh"
 #include "AboutWindow.hh"
+#include "VivyFileIconProvider.hh"
 #include "../Lib/Utils.hh"
 #include "../VivyApplication.hh"
 
@@ -11,6 +12,8 @@
 #include <QWindow>
 #include <optional>
 #include <QTreeView>
+#include <QPushButton>
+#include <QDialogButtonBox>
 #include <QFileInfo>
 #include <QStandardPaths>
 #include <QPixmap>
@@ -239,7 +242,30 @@ MainWindow::newDocument() noexcept
 void
 MainWindow::openDocument() noexcept
 {
-    QString filename = QFileDialog::getOpenFileName(this, "Select a file");
+    QFileDialog dialog(this, "Select a file");
+    bool dialogAccepted = false;
+    std::unique_ptr<VivyFileIconProvider> iconProvider(new VivyFileIconProvider());
+    dialog.setOption(QFileDialog::DontUseNativeDialog);
+    dialog.setOption(QFileDialog::ReadOnly);
+    dialog.setIconProvider(iconProvider.get());
+    dialog.setFileMode(QFileDialog::ExistingFile);
+    connect(&dialog, &QFileDialog::accepted, this,
+            [&dialogAccepted]() noexcept -> void { dialogAccepted = true; });
+    dialog.exec();
+
+    if (!dialogAccepted) {
+        qDebug() << "No file accepted";
+        return;
+    }
+
+    const QStringList resList = dialog.selectedFiles();
+    if (resList.size() != 1) {
+        qCritical() << "You must select only one file";
+        return;
+    }
+
+    const QString filename = resList.at(0);
+
     if (filename.isEmpty()) {
         qWarning() << "Found an empty filename, don't open a file";
         return;
diff --git a/src/UI/VivyFileIconProvider.cc b/src/UI/VivyFileIconProvider.cc
new file mode 100644
index 00000000..0993d18f
--- /dev/null
+++ b/src/UI/VivyFileIconProvider.cc
@@ -0,0 +1,18 @@
+#include "VivyFileIconProvider.hh"
+#include "../VivyApplication.hh"
+
+using namespace Vivy;
+
+QIcon
+VivyFileIconProvider::icon(const QFileInfo &info) const noexcept
+{
+    if (const auto name = info.fileName(); name.isEmpty() || name.isNull())
+        return defaultFile;
+    // TODO: For file detection use functions in Utils.hh
+    else if (info.isDir())
+        return defaultFolder;
+    else if (const auto suffix = info.suffix(); suffix == "vivy" || suffix == "ass")
+        return vivyFile;
+    else
+        return defaultFile;
+}
diff --git a/src/UI/VivyFileIconProvider.hh b/src/UI/VivyFileIconProvider.hh
new file mode 100644
index 00000000..c220d5b2
--- /dev/null
+++ b/src/UI/VivyFileIconProvider.hh
@@ -0,0 +1,27 @@
+#pragma once
+
+#ifndef __cplusplus
+#error "This is a C++ header"
+#endif
+
+#include "../Lib/Utils.hh"
+#include "../VivyApplication.hh"
+#include <QtGlobal>
+#include <QFileIconProvider>
+#include <QFileInfo>
+#include <QIcon>
+
+namespace Vivy
+{
+class VivyFileIconProvider : public QFileIconProvider {
+public:
+    VivyFileIconProvider() noexcept = default;
+
+    QIcon icon(const QFileInfo &) const noexcept override;
+
+private:
+    QIcon defaultFile{ VIVY_ICON_FILE };
+    QIcon vivyFile{ VIVY_ICON_APP };
+    QIcon defaultFolder{ VIVY_ICON_FOLDER };
+};
+}
diff --git a/src/VivyApplication.hh b/src/VivyApplication.hh
index 86c5f89d..384647d2 100644
--- a/src/VivyApplication.hh
+++ b/src/VivyApplication.hh
@@ -13,6 +13,8 @@
 #define VIVY_ICON_SAVE    ":icons/dark/document-save.svg"
 #define VIVY_ICON_SAVE_AS ":icons/dark/document-save-as.svg"
 #define VIVY_ICON_ABOUT   ":icons/dark/help-about.svg"
+#define VIVY_ICON_FILE    ":icons/dark/"
+#define VIVY_ICON_FOLDER  ":icons/dark/"
 
 #include <QApplication>
 #include <QPixmap>
-- 
GitLab