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) 2025 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 "notationstyle.h"
23 :
24 : #include "io/file.h"
25 : #include "io/fileinfo.h"
26 : #include "types/translatablestring.h"
27 :
28 : #include "engraving/dom/masterscore.h"
29 : #include "engraving/dom/excerpt.h"
30 : #include "engraving/editing/editstyle.h"
31 : #include "engraving/editing/editstavesharing.h"
32 : #include "engraving/editing/reset.h"
33 : #include "engraving/editing/transaction/transaction.h"
34 : #include "engraving/style/defaultstyle.h"
35 :
36 : #include "log.h"
37 :
38 : using namespace mu::notation;
39 : using namespace muse::async;
40 :
41 0 : NotationStyle::NotationStyle(IGetScore* getScore, INotationUndoStackPtr undoStack)
42 0 : : m_getScore(getScore), m_undoStack(undoStack)
43 : {
44 0 : }
45 :
46 0 : const PropertyValue& NotationStyle::styleValue(const StyleId& styleId) const
47 : {
48 0 : return score()->style().styleV(styleId);
49 : }
50 :
51 0 : const PropertyValue& NotationStyle::defaultStyleValue(const StyleId& styleId) const
52 : {
53 0 : return engraving::DefaultStyle::defaultStyle().value(styleId);
54 : }
55 :
56 0 : void NotationStyle::setStyleValue(const StyleId& styleId, const PropertyValue& newValue)
57 : {
58 0 : if (styleValue(styleId) == newValue) {
59 0 : return;
60 : }
61 :
62 0 : if (styleId == StyleId::concertPitch) {
63 0 : score()->cmdConcertPitchChanged(newValue.toBool());
64 : } else {
65 0 : score()->undoChangeStyleVal(styleId, newValue);
66 0 : score()->update();
67 : }
68 :
69 0 : m_styleChanged.notify();
70 : }
71 :
72 0 : void NotationStyle::resetStyleValue(const StyleId& styleId)
73 : {
74 0 : score()->resetStyleValue(styleId);
75 0 : score()->update();
76 0 : m_styleChanged.notify();
77 0 : }
78 :
79 0 : void NotationStyle::resetStyleValues(const std::vector<StyleId>& styleIds)
80 : {
81 0 : for (StyleId id : styleIds) {
82 0 : score()->resetStyleValue(id);
83 : }
84 0 : score()->update();
85 0 : m_styleChanged.notify();
86 0 : }
87 :
88 0 : bool NotationStyle::canApplyToAllParts() const
89 : {
90 0 : return !score()->isMaster(); // In parts only
91 : }
92 :
93 0 : void NotationStyle::applyToAllParts()
94 : {
95 0 : if (!canApplyToAllParts()) {
96 0 : return;
97 : }
98 :
99 0 : mu::engraving::MStyle style = m_getScore->score()->style();
100 :
101 0 : for (mu::engraving::Excerpt* excerpt : score()->masterScore()->excerpts()) {
102 0 : excerpt->excerptScore()->undo(new mu::engraving::ChangeStyle(excerpt->excerptScore(), style));
103 0 : excerpt->excerptScore()->update();
104 : }
105 0 : }
106 :
107 0 : void NotationStyle::resetAllStyleValues(const StyleIdSet& exceptTheseOnes)
108 : {
109 0 : mu::engraving::Reset::resetAllStyles(score()->transactionManager()->currentOrDummyTransaction(), score(), exceptTheseOnes);
110 0 : score()->update();
111 0 : m_styleChanged.notify();
112 0 : }
113 :
114 0 : Notification NotationStyle::styleChanged() const
115 : {
116 0 : return m_styleChanged;
117 : }
118 :
119 0 : bool NotationStyle::loadStyle(const muse::io::path_t& path, bool allowAnyVersion)
120 : {
121 0 : m_undoStack->prepareChanges(muse::TranslatableString("undoableAction", "Load style"));
122 0 : muse::io::File styleFile(path);
123 0 : bool result = mu::engraving::EditStyle::loadStyle(score()->transactionManager()->currentOrDummyTransaction(), score(), styleFile,
124 : allowAnyVersion);
125 0 : m_undoStack->commitChanges();
126 :
127 0 : if (result) {
128 0 : styleChanged().notify();
129 : }
130 :
131 0 : return result;
132 0 : }
133 :
134 0 : bool NotationStyle::saveStyle(const muse::io::path_t& path)
135 : {
136 0 : muse::io::path_t filePath = muse::io::FileInfo(path).suffix().isEmpty() ? path.appendingSuffix("mss") : path;
137 :
138 0 : muse::io::File styleFile(filePath);
139 0 : if (!styleFile.open(muse::io::IODevice::WriteOnly) || !score()->style().write(&styleFile)) {
140 0 : LOGE() << "Failed to write style file: " << filePath.toString();
141 0 : return false;
142 : }
143 :
144 0 : styleFile.close();
145 0 : return true;
146 0 : }
147 :
148 0 : mu::engraving::Score* NotationStyle::score() const
149 : {
150 0 : return m_getScore->score();
151 : }
|