Loading...
Searching...
No Matches
FileSystemModel.hpp
1#pragma once
2#include <Library/LibraryInterface.hpp>
3
4#include <score/application/GUIApplicationContext.hpp>
5#include <score/tools/std/StringHash.hpp>
6#include <score/widgets/IconProvider.hpp>
7
8#include <QFileIconProvider>
9#include <QFileSystemModel>
10#include <QGuiApplication>
11#include <QMimeData>
12#include <QSet>
13
14#include <ossia/detail/hash_map.hpp>
15#include <ossia/detail/hash_map.hpp>
16
17namespace Library
18{
19
20class FileSystemModel : public QFileSystemModel
21{
22public:
23 FileSystemModel(const score::GUIApplicationContext& ctx, QObject* parent)
24 : QFileSystemModel{parent}
25 {
26 setIconProvider(&score::IconProvider::instance());
27
28 auto& lib_setup = ctx.interfaces<Library::LibraryInterfaceList>();
29 // TODO refactor
30 QSet<QString> types{// score-specific
31 "*.score",
32 "*.cue",
33 "*.device",
34 "*.oscquery",
35 "*.json"
36
37 // JS scripts
38 ,
39 "*.js",
40 "*.qml",
41 "*.script"
42
43 // Faust, other audio stuff
44 ,
45 "*.dsp",
46 "*.mid"};
47
48 for(const LibraryInterface& lib : lib_setup)
49 {
50 auto lst = lib.acceptedFiles();
51 for(const auto& ext : lib.acceptedFiles())
52 {
53 types.insert("*." + ext);
54 }
55 }
56
57 // QFileSystemModel is case-sensitive, so we at least handle the ALL-CAPS EXTENSIONS
58 // **floppy drive noises buzzing in the background**
59 {
60 auto copy = types;
61 for(auto t : copy)
62 {
63 types.insert(t.toUpper());
64 }
65 }
66
67 setNameFilters(types.values());
68 setResolveSymlinks(true);
69 setFilter(QDir::AllDirs | QDir::Files | QDir::NoDotAndDotDot);
70
71 for(auto& lib : lib_setup)
72 {
73 for(const auto& str : lib.acceptedMimeTypes())
74 {
75 m_mimeTypes.push_back(str);
76 m_mimeActions[str] = &lib;
77 }
78 }
79 }
80
81#if defined(__clang__)
82 static constexpr bool supportsDisablingSorting() noexcept
83 {
84 return []<typename T>(T* fsm) constexpr {
85 return requires { fsm->setOption(T::DontSort); };
86 }((QFileSystemModel*)nullptr);
87 }
88
89 void setSorting(bool b) noexcept
90 {
91 [b]<typename T>(T& self) {
92 if constexpr(T::supportsDisablingSorting())
93 {
94 static_assert(T::supportsDisablingSorting());
95 self.setOption(T::DontSort, !b);
96 }
97 }(*this);
98 }
99
100 bool isSorting() noexcept
101 {
102 return []<typename T>(T& fsm) {
103 if constexpr(supportsDisablingSorting())
104 {
105 static_assert(requires { fsm.setOption(T::DontSort); });
106 return !fsm.testOption(T::DontSort);
107 }
108 else
109 {
110 return true;
111 }
112 }(*this);
113 }
114#else
115 static constexpr bool supportsDisablingSorting() noexcept { return false; }
116 void setSorting(bool b) noexcept { }
117 bool isSorting() noexcept { return true; }
118#endif
119
120 Qt::ItemFlags flags(const QModelIndex& index) const override
121 {
122 Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsDragEnabled
123 | Qt::ItemIsDropEnabled;
124
125 if(!isDir(index))
126 f |= Qt::ItemIsEditable;
127
128 return f;
129 }
130
131 QStringList mimeTypes() const override { return m_mimeTypes; }
132
133 bool dropMimeData(
134 const QMimeData* data, Qt::DropAction action, int row, int column,
135 const QModelIndex& parent) override
136 {
137 const QFileInfo f = fileInfo(parent);
138 const QDir d = f.isDir() ? QDir(f.canonicalFilePath()) : f.absoluteDir();
139 for(const auto& fmt : data->formats())
140 {
141 auto it = m_mimeActions.find(fmt);
142 if(it != m_mimeActions.end())
143 {
144 if(it->second->onDrop(*data, row, column, d))
145 return true;
146 }
147 }
148
149 return false;
150 }
151
152 QVariant data(const QModelIndex& index, int role) const override
153 {
154 if(role == Qt::DecorationRole)
155 {
156 if(isDir(index))
157 return score::IconProvider::folderIcon();
158 else
159 return {};
160 }
161 return QFileSystemModel::data(index, role);
162 }
163
164 QStringList m_mimeTypes;
165 ossia::hash_map<QString, LibraryInterface*> m_mimeActions;
166};
167}
Definition FileSystemModel.hpp:21
Definition LibraryInterface.hpp:22
Definition LibraryInterface.hpp:44
void insert(std::unique_ptr< score::InterfaceBase > e) final override
insert Register a new factory.
Definition InterfaceList.hpp:98
const T & interfaces() const
Access to a specific interface list.
Definition ApplicationContext.hpp:67
Specializes ApplicationContext with the QMainWindow.
Definition GUIApplicationContext.hpp:15