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) 2022 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 "soundprofilesmodel.h"
24 :
25 : #include "notation/imasternotation.h" // IWYU pragma: keep
26 : #include "notation/inotationplayback.h"
27 :
28 : #include "project/inotationproject.h"
29 : #include "project/iprojectaudiosettings.h" // IWYU pragma: keep
30 :
31 : using namespace mu::playback;
32 : using namespace mu::project;
33 :
34 0 : SoundProfilesModel::SoundProfilesModel(QObject* parent)
35 0 : : QAbstractListModel(parent), muse::Contextable(muse::iocCtxForQmlObject(this))
36 : {
37 0 : }
38 :
39 0 : void SoundProfilesModel::init()
40 : {
41 0 : beginResetModel();
42 :
43 0 : const SoundProfilesMap& availableProfiles = profilesRepo()->availableProfiles();
44 0 : for (const auto& pair : availableProfiles) {
45 0 : m_profiles.push_back(pair.second);
46 : }
47 :
48 0 : std::sort(m_profiles.begin(), m_profiles.end(), [this](const SoundProfile& left, const SoundProfile& right) {
49 0 : if (left.name == config()->basicSoundProfileName()
50 0 : && right.name == config()->museSoundsProfileName()) {
51 0 : return true;
52 : }
53 :
54 0 : return false;
55 : });
56 :
57 0 : if (INotationProjectPtr project = context()->project()) {
58 0 : m_activeProfile = project->audioSettings()->activeSoundProfile().toQString();
59 0 : m_currentlySelectedProfile = m_activeProfile;
60 0 : }
61 :
62 0 : m_defaultProjectsProfile = config()->defaultProfileForNewProjects().toQString();
63 :
64 0 : endResetModel();
65 0 : }
66 :
67 0 : int SoundProfilesModel::rowCount(const QModelIndex& /*parent*/) const
68 : {
69 0 : return static_cast<int>(m_profiles.size());
70 : }
71 :
72 0 : QVariant SoundProfilesModel::data(const QModelIndex& index, int role) const
73 : {
74 0 : if (!index.isValid()
75 0 : || m_profiles.empty()
76 0 : || index.row() > static_cast<int>(m_profiles.size() - 1)) {
77 0 : return QVariant();
78 : }
79 :
80 0 : const SoundProfile& profile = m_profiles.at(index.row());
81 :
82 0 : switch (role) {
83 0 : case RoleTitle:
84 0 : return profile.name.toQString();
85 0 : case RoleEnabled:
86 0 : return profile.isEnabled();
87 : }
88 :
89 0 : return QVariant();
90 : }
91 :
92 0 : QHash<int, QByteArray> SoundProfilesModel::roleNames() const
93 : {
94 : static const QHash<int, QByteArray> roles {
95 0 : { RoleTitle, "title" },
96 0 : { RoleEnabled, "isEnabled" }
97 0 : };
98 :
99 0 : return roles;
100 0 : }
101 :
102 0 : const QString& SoundProfilesModel::activeProfile() const
103 : {
104 0 : return m_activeProfile;
105 : }
106 :
107 0 : void SoundProfilesModel::setActiveProfile(const QString& newActiveProfile)
108 : {
109 0 : if (m_activeProfile == newActiveProfile) {
110 0 : return;
111 : }
112 :
113 0 : if (!askAboutChangingSounds()) {
114 0 : return;
115 : }
116 :
117 0 : m_activeProfile = newActiveProfile;
118 :
119 0 : if (INotationProjectPtr project = context()->project()) {
120 0 : SoundProfileName activeProfileName = SoundProfileName::fromQString(newActiveProfile);
121 0 : project->audioSettings()->setActiveSoundProfile(activeProfileName);
122 0 : controller()->applyProfile(activeProfileName);
123 0 : }
124 :
125 0 : emit activeProfileChanged();
126 : }
127 :
128 0 : const QString& SoundProfilesModel::defaultProjectsProfile() const
129 : {
130 0 : return m_defaultProjectsProfile;
131 : }
132 :
133 0 : void SoundProfilesModel::setDefaultProjectsProfile(const QString& newDefaultProjectsProfile)
134 : {
135 0 : if (m_defaultProjectsProfile == newDefaultProjectsProfile) {
136 0 : return;
137 : }
138 :
139 0 : m_defaultProjectsProfile = newDefaultProjectsProfile;
140 0 : config()->setDefaultProfileForNewProjects(SoundProfileName::fromQString(newDefaultProjectsProfile));
141 :
142 0 : emit defaultProjectsProfileChanged();
143 : }
144 :
145 0 : mu::notation::INotationPlaybackPtr SoundProfilesModel::notationPlayback() const
146 : {
147 0 : project::INotationProjectPtr project = context()->project();
148 0 : return project ? project->masterNotation()->playback() : nullptr;
149 0 : }
150 :
151 0 : bool SoundProfilesModel::askAboutChangingSounds()
152 : {
153 0 : if (!config()->needToShowResetSoundFlagsWhenChangePlaybackProfileWarning()) {
154 0 : return true;
155 : }
156 :
157 0 : if (!notationPlayback()->hasSoundFlags(notationPlayback()->existingTrackIdSet())) {
158 0 : return true;
159 : }
160 :
161 0 : int changeBtn = int(muse::IInteractive::Button::Apply);
162 0 : muse::IInteractive::Options options = muse::IInteractive::Option::WithIcon | muse::IInteractive::Option::WithDontShowAgainCheckBox;
163 : muse::IInteractive::ButtonDatas buttons = {
164 0 : interactive()->buttonData(muse::IInteractive::Button::Cancel),
165 0 : muse::IInteractive::ButtonData(changeBtn, muse::trc("playback", "Change sounds"), true /*accent*/)
166 0 : };
167 :
168 0 : muse::IInteractive::Result result = interactive()->warningSync(muse::trc("playback", "Are you sure you want to change sounds?"),
169 0 : muse::trc("playback",
170 : "Sound flags may be reset, but staff text will remain. This action can’t be undone."),
171 : buttons, changeBtn, options);
172 :
173 0 : if (result.button() == changeBtn) {
174 0 : if (!result.showAgain()) {
175 0 : config()->setNeedToShowResetSoundFlagsWhenChangePlaybackProfileWarning(false);
176 : }
177 :
178 0 : return true;
179 : } else {
180 0 : return false;
181 : }
182 0 : }
183 :
184 0 : const QString& SoundProfilesModel::currentlySelectedProfile() const
185 : {
186 0 : return m_currentlySelectedProfile;
187 : }
188 :
189 0 : void SoundProfilesModel::setCurrentlySelectedProfile(const QString& newCurrentlySelectedProfile)
190 : {
191 0 : if (m_currentlySelectedProfile == newCurrentlySelectedProfile) {
192 0 : return;
193 : }
194 0 : m_currentlySelectedProfile = newCurrentlySelectedProfile;
195 0 : emit currentlySelectedProfileChanged();
196 : }
|