Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2026 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 :
23 : #include "generalsoundfontinstallscenario.h"
24 :
25 : #include "global/translation.h"
26 :
27 : using namespace muse;
28 : using namespace muse::audio;
29 :
30 0 : void GeneralSoundFontInstallScenario::installSoundFont(const synth::SoundFontUri& uri)
31 : {
32 0 : io::path_t path = uri.toLocalFile();
33 0 : std::string title = muse::qtrc("audio", "Do you want to add SoundFont %1?")
34 0 : .arg(io::filename(path).toQString()).toStdString();
35 :
36 0 : interactive()->question(title, "", {
37 : IInteractive::Button::No,
38 : IInteractive::Button::Yes
39 : })
40 0 : .onResolve(this, [this, path](const IInteractive::Result& res) {
41 0 : if (res.isButton(IInteractive::Button::No)) {
42 0 : LOGI() << "soundfont addition cancelled";
43 0 : return;
44 : }
45 :
46 0 : RetVal<io::path_t> newPath = resolveInstallationPath(path);
47 0 : if (!newPath.ret) {
48 0 : LOGE() << "failed resolve path, err: " << newPath.ret.toString();
49 0 : return;
50 : }
51 :
52 0 : if (fileSystem()->exists(newPath.val)) {
53 0 : std::string title = muse::trc("audio", "File already exists. Do you want to overwrite it?");
54 :
55 0 : std::string body = muse::qtrc("audio", "File path: %1")
56 0 : .arg(newPath.val.toQString()).toStdString();
57 :
58 0 : interactive()->question(title, body, {
59 : IInteractive::Button::No,
60 : IInteractive::Button::Yes
61 : }, IInteractive::Button::Yes, IInteractive::WithIcon)
62 0 : .onResolve(this, [this, path, newPath](const IInteractive::Result& res) {
63 0 : if (res.isButton(IInteractive::Button::No)) {
64 0 : LOGI() << "soundfont replacement cancelled";
65 0 : return;
66 : }
67 :
68 0 : Ret ret = doAddSoundFont(path, newPath.val);
69 0 : if (ret) {
70 0 : interactive()->info(muse::trc("audio", "SoundFont installed"),
71 0 : muse::trc("audio", "You can assign soundfonts to instruments using the mixer panel."),
72 : {}, 0, IInteractive::Option::WithIcon);
73 : } else {
74 0 : LOGE() << "failed add soundfont, err: " << ret.toString();
75 : }
76 0 : });
77 0 : } else {
78 0 : Ret ret = doAddSoundFont(path, newPath.val);
79 0 : if (ret) {
80 0 : interactive()->info(muse::trc("audio", "SoundFont installed"),
81 0 : muse::trc("audio", "You can assign soundfonts to instruments using the mixer panel."),
82 : {}, 0, IInteractive::Option::WithIcon);
83 : } else {
84 0 : LOGE() << "failed add soundfont, err: " << ret.toString();
85 : }
86 0 : }
87 0 : });
88 0 : }
89 :
90 0 : RetVal<io::path_t> GeneralSoundFontInstallScenario::resolveInstallationPath(const io::path_t& path) const
91 : {
92 0 : io::paths_t dirs = configuration()->userSoundFontDirectories();
93 :
94 0 : for (const io::path_t& dir : dirs) {
95 0 : if (fileSystem()->isWritable(dir)) {
96 0 : io::path_t newPath = dir + "/" + io::filename(path);
97 0 : return RetVal<io::path_t>::make_ok(newPath);
98 0 : }
99 : }
100 :
101 0 : return RetVal<io::path_t>(make_ret(Ret::Code::UnknownError));
102 0 : }
103 :
104 0 : Ret GeneralSoundFontInstallScenario::doAddSoundFont(const io::path_t& src, const io::path_t& dst)
105 : {
106 0 : Ret ret = fileSystem()->copy(src, dst, true /* replace */);
107 :
108 0 : if (ret) {
109 0 : synth::SoundFontUri uri = synth::SoundFontUri::fromLocalFile(dst);
110 0 : soundFontController()->addSoundFont(uri);
111 0 : }
112 :
113 0 : return ret;
114 0 : }
|