Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 : #include "folderspreferencesmodel.h"
23 :
24 : #include "translation.h"
25 :
26 : #include "muse_framework_config.h"
27 :
28 : using namespace mu::preferences;
29 : using namespace muse;
30 :
31 0 : FoldersPreferencesModel::FoldersPreferencesModel(QObject* parent)
32 0 : : QAbstractListModel(parent), muse::Contextable(muse::iocCtxForQmlObject(this))
33 : {
34 0 : }
35 :
36 0 : bool FoldersPreferencesModel::vstEnabled() const
37 : {
38 : #ifdef MUSE_MODULE_VST
39 0 : return true;
40 : #else
41 : return false;
42 : #endif
43 : }
44 :
45 0 : int FoldersPreferencesModel::rowCount(const QModelIndex&) const
46 : {
47 0 : return m_folders.count();
48 : }
49 :
50 0 : QVariant FoldersPreferencesModel::data(const QModelIndex& index, int role) const
51 : {
52 0 : const FolderInfo& folder = m_folders.at(index.row());
53 0 : switch (role) {
54 0 : case TitleRole: return folder.title;
55 0 : case PathRole: return folder.value;
56 0 : case DirRole: return folder.dir;
57 0 : case IsMultiDirectoriesRole: return folder.valueType == FolderValueType::MultiDirectories;
58 : }
59 :
60 0 : return QVariant();
61 : }
62 :
63 0 : bool FoldersPreferencesModel::setData(const QModelIndex& index, const QVariant& value, int role)
64 : {
65 0 : const FolderInfo& folder = m_folders.at(index.row());
66 :
67 0 : switch (role) {
68 0 : case PathRole:
69 0 : if (folder.value == value.toString()) {
70 0 : return false;
71 : }
72 :
73 0 : saveFolderPaths(folder.type, value.toString());
74 0 : return true;
75 0 : default:
76 0 : break;
77 : }
78 :
79 0 : return false;
80 : }
81 :
82 0 : QHash<int, QByteArray> FoldersPreferencesModel::roleNames() const
83 : {
84 : static const QHash<int, QByteArray> roles = {
85 0 : { TitleRole, "title" },
86 0 : { PathRole, "path" },
87 0 : { DirRole, "dir" },
88 0 : { IsMultiDirectoriesRole, "isMultiDirectories" }
89 0 : };
90 :
91 0 : return roles;
92 0 : }
93 :
94 0 : void FoldersPreferencesModel::load()
95 : {
96 0 : beginResetModel();
97 :
98 0 : m_folders = {
99 : {
100 0 : FolderType::Scores, muse::qtrc("preferences", "Scores"), projectConfiguration()->userProjectsPath().toQString(),
101 0 : projectConfiguration()->userProjectsPath().toQString()
102 : },
103 : {
104 0 : FolderType::Styles, muse::qtrc("preferences", "Styles"), notationConfiguration()->userStylesPath().toQString(),
105 0 : notationConfiguration()->userStylesPath().toQString()
106 : },
107 : {
108 : FolderType::Instruments, muse::qtrc("preferences", "Instruments and score orders"),
109 0 : notationConfiguration()->userInstrumentsFolder().toQString(),
110 0 : notationConfiguration()->userInstrumentsFolder().toQString()
111 : },
112 : {
113 0 : FolderType::Templates, muse::qtrc("preferences", "Templates"), projectConfiguration()->userTemplatesPath().toQString(),
114 0 : projectConfiguration()->userTemplatesPath().toQString()
115 : },
116 : {
117 0 : FolderType::Plugins, muse::qtrc("preferences", "Plugins"), extensionsConfiguration()->pluginsUserPath().toQString(),
118 0 : extensionsConfiguration()->pluginsUserPath().toQString()
119 : },
120 : {
121 : FolderType::SoundFonts, muse::qtrc("preferences", "SoundFonts"), pathsToString(
122 0 : audioConfiguration()->userSoundFontDirectories()),
123 0 : globalConfiguration()->userDataPath().toQString(), FolderValueType::MultiDirectories
124 : },
125 : {
126 : FolderType::MusicFonts, muse::qtrc("preferences", "Musical symbol fonts"),
127 0 : notationConfiguration()->userMusicFontsPath().toQString(),
128 0 : notationConfiguration()->userMusicFontsPath().toQString()
129 : },
130 : #ifdef MUSE_MODULE_VST
131 : {
132 0 : FolderType::VST3, muse::qtrc("preferences", "VST3"), pathsToString(vstConfiguration()->userVstDirectories()),
133 0 : globalConfiguration()->userDataPath().toQString(), FolderValueType::MultiDirectories
134 : }
135 : #endif
136 0 : };
137 :
138 0 : endResetModel();
139 :
140 0 : setupConnections();
141 0 : }
142 :
143 0 : void FoldersPreferencesModel::setupConnections()
144 : {
145 0 : projectConfiguration()->userProjectsPathChanged().onReceive(this, [this](const muse::io::path_t& path) {
146 0 : setFolderPaths(FolderType::Scores, path.toQString());
147 0 : });
148 :
149 0 : notationConfiguration()->userStylesPathChanged().onReceive(this, [this](const muse::io::path_t& path) {
150 0 : setFolderPaths(FolderType::Styles, path.toQString());
151 0 : });
152 :
153 0 : notationConfiguration()->userInstrumentsFolderChanged().onReceive(this, [this](const muse::io::path_t& path) {
154 0 : setFolderPaths(FolderType::Instruments, path.toQString());
155 0 : });
156 :
157 0 : projectConfiguration()->userTemplatesPathChanged().onReceive(this, [this](const muse::io::path_t& path) {
158 0 : setFolderPaths(FolderType::Templates, path.toQString());
159 0 : });
160 :
161 0 : extensionsConfiguration()->pluginsUserPathChanged().onReceive(this, [this](const muse::io::path_t& path) {
162 0 : setFolderPaths(FolderType::Plugins, path.toQString());
163 0 : });
164 :
165 0 : audioConfiguration()->soundFontDirectoriesChanged().onReceive(this, [this](const io::paths_t&) {
166 0 : io::paths_t userSoundFontsPaths = audioConfiguration()->userSoundFontDirectories();
167 0 : setFolderPaths(FolderType::SoundFonts, pathsToString(userSoundFontsPaths));
168 0 : });
169 :
170 0 : notationConfiguration()->userMusicFontsPathChanged().onReceive(this, [this](const muse::io::path_t& path) {
171 0 : setFolderPaths(FolderType::MusicFonts, path.toQString());
172 0 : });
173 :
174 0 : vstConfiguration()->userVstDirectoriesChanged().onReceive(this, [this](const io::paths_t& paths) {
175 0 : setFolderPaths(FolderType::VST3, pathsToString(paths));
176 0 : });
177 0 : }
178 :
179 0 : void FoldersPreferencesModel::saveFolderPaths(FoldersPreferencesModel::FolderType folderType, const QString& paths)
180 : {
181 0 : switch (folderType) {
182 0 : case FolderType::Scores: {
183 0 : muse::io::path_t folderPath = paths.toStdString();
184 0 : projectConfiguration()->setUserProjectsPath(folderPath);
185 0 : break;
186 0 : }
187 0 : case FolderType::Styles: {
188 0 : muse::io::path_t folderPath = paths.toStdString();
189 0 : notationConfiguration()->setUserStylesPath(folderPath);
190 0 : break;
191 0 : }
192 0 : case FolderType::Instruments: {
193 0 : muse::io::path_t folderPath = paths.toStdString();
194 0 : notationConfiguration()->setUserInstrumentsFolder(folderPath);
195 0 : break;
196 0 : }
197 0 : case FolderType::Templates: {
198 0 : muse::io::path_t folderPath = paths.toStdString();
199 0 : projectConfiguration()->setUserTemplatesPath(folderPath);
200 0 : break;
201 0 : }
202 0 : case FolderType::Plugins: {
203 0 : muse::io::path_t folderPath = paths.toStdString();
204 0 : extensionsConfiguration()->setUserPluginsPath(folderPath);
205 0 : break;
206 0 : }
207 0 : case FolderType::SoundFonts: {
208 0 : audioConfiguration()->setUserSoundFontDirectories(pathsFromString(paths));
209 0 : break;
210 : }
211 0 : case FolderType::MusicFonts: {
212 0 : notationConfiguration()->setUserMusicFontsPath(paths.toStdString());
213 0 : break;
214 : }
215 0 : case FolderType::VST3: {
216 0 : vstConfiguration()->setUserVstDirectories(pathsFromString(paths));
217 0 : break;
218 : }
219 0 : case FolderType::Undefined:
220 0 : break;
221 : }
222 0 : }
223 :
224 0 : void FoldersPreferencesModel::setFolderPaths(FoldersPreferencesModel::FolderType folderType, const QString& paths)
225 : {
226 0 : QModelIndex index = folderIndex(folderType);
227 0 : if (!index.isValid()) {
228 0 : return;
229 : }
230 :
231 0 : m_folders[index.row()].value = paths;
232 0 : emit dataChanged(index, index, { PathRole });
233 : }
234 :
235 0 : QModelIndex FoldersPreferencesModel::folderIndex(FoldersPreferencesModel::FolderType folderType)
236 : {
237 0 : for (int i = 0; i < m_folders.count(); ++i) {
238 0 : FolderInfo& folderInfo = m_folders[i];
239 0 : if (folderInfo.type == folderType) {
240 0 : return index(i, 0);
241 : }
242 : }
243 :
244 0 : return QModelIndex();
245 : }
246 :
247 0 : void FoldersPreferencesModel::rescanVstPlugins()
248 : {
249 0 : if (registerAudioPluginsScenario()) {
250 0 : registerAudioPluginsScenario()->rescanAllPlugins();
251 : }
252 0 : }
253 :
254 0 : QString FoldersPreferencesModel::pathsToString(const io::paths_t& paths) const
255 : {
256 0 : return QString::fromStdString(io::pathsToString(paths));
257 : }
258 :
259 0 : io::paths_t FoldersPreferencesModel::pathsFromString(const QString& pathsStr) const
260 : {
261 0 : return io::pathsFromString(pathsStr.toStdString());
262 : }
|