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 :
23 : #include "editstyle.h"
24 :
25 : #include "../dom/chordlist.h"
26 : #include "../dom/score.h"
27 : #include "editing/editpagelocks.h"
28 : #include "editing/editsystemlocks.h"
29 : #include "editing/transaction/transaction.h"
30 :
31 : #include "log.h"
32 :
33 : using namespace mu::engraving;
34 :
35 2 : static void changeChordStyle(Score* score)
36 : {
37 2 : const MStyle& style = score->style();
38 2 : score->chordList()->unload();
39 2 : double emag = style.styleD(Sid::chordExtensionMag);
40 2 : double eadjust = style.styleD(Sid::chordExtensionAdjust);
41 2 : double mmag = style.styleD(Sid::chordModifierMag);
42 2 : double madjust = style.styleD(Sid::chordModifierAdjust);
43 2 : double stackedmmag = style.styleD(Sid::chordStackedModifierMag);
44 2 : bool mstackModifiers = style.styleB(Sid::verticallyStackModifiers);
45 2 : bool mexcludeModsHAlign = style.styleB(Sid::chordAlignmentExcludeModifiers);
46 2 : String msymbolFont = style.styleSt(Sid::musicalTextFont);
47 2 : ChordStylePreset preset = style.styleV(Sid::chordStyle).value<ChordStylePreset>();
48 2 : score->chordList()->configureAutoAdjust(emag, eadjust, mmag, madjust, stackedmmag, mstackModifiers, mexcludeModsHAlign, msymbolFont,
49 : preset);
50 2 : if (score->style().styleB(Sid::chordsXmlFile)) {
51 0 : score->chordList()->read(u"chords.xml");
52 : }
53 2 : score->chordList()->read(style.styleSt(Sid::chordDescriptionFile));
54 2 : score->chordList()->setCustomChordList(style.styleV(Sid::chordStyle).value<ChordStylePreset>() == ChordStylePreset::CUSTOM);
55 2 : }
56 :
57 : //---------------------------------------------------------
58 : // ChangeStyle
59 : //----------------------------------------------------------
60 :
61 1 : ChangeStyle::ChangeStyle(Score* s, const MStyle& st, const bool overlapOnly)
62 1 : : score(s), style(st), overlap(overlapOnly)
63 : {
64 1 : }
65 :
66 1 : StyleIdSet ChangeStyle::changedIds() const
67 : {
68 1 : StyleIdSet result;
69 2055 : for (int _sid = 0; _sid < static_cast<int>(Sid::STYLES); ++_sid) {
70 2054 : Sid sid = static_cast<Sid>(_sid);
71 2054 : if (score->style().styleV(sid) != style.value(sid)) {
72 1 : result.insert(sid);
73 : }
74 : }
75 1 : return result;
76 0 : }
77 :
78 2 : void ChangeStyle::flip()
79 : {
80 2 : MStyle tmp = score->style();
81 :
82 2 : if (score->style().styleV(Sid::concertPitch) != style.value(Sid::concertPitch)) {
83 0 : score->cmdConcertPitchChanged(style.value(Sid::concertPitch).toBool());
84 : }
85 2 : if (score->style().styleV(Sid::musicalSymbolFont) != style.value(Sid::musicalSymbolFont)) {
86 0 : score->setEngravingFont(score->engravingFonts()->fontByName(style.styleSt(Sid::musicalSymbolFont).toStdString()));
87 : }
88 :
89 2 : score->setStyle(style, overlap);
90 2 : changeChordStyle(score);
91 2 : if (tmp.spatium() != style.spatium()) {
92 0 : score->spatiumChanged(tmp.spatium(), style.spatium());
93 : }
94 2 : score->styleChanged();
95 2 : style = tmp;
96 2 : }
97 :
98 1 : void ChangeStyle::undo()
99 : {
100 1 : overlap = false;
101 1 : UndoableCommand::undo();
102 1 : }
103 :
104 : //---------------------------------------------------------
105 : // ChangeStyleValues
106 : //----------------------------------------------------------
107 :
108 57 : static void changeStyleValue(Score* score, Sid idx, const PropertyValue& oldValue, const PropertyValue& newValue)
109 : {
110 57 : score->style().set(idx, newValue);
111 57 : switch (idx) {
112 0 : case Sid::chordExtensionMag:
113 : case Sid::chordExtensionAdjust:
114 : case Sid::chordModifierMag:
115 : case Sid::chordModifierAdjust:
116 : case Sid::chordDescriptionFile:
117 : case Sid::verticallyStackModifiers:
118 : case Sid::chordAlignmentExcludeModifiers:
119 : case Sid::musicalTextFont: {
120 0 : changeChordStyle(score);
121 : }
122 0 : break;
123 0 : case Sid::spatium:
124 0 : score->spatiumChanged(oldValue.toDouble(), newValue.toDouble());
125 0 : break;
126 0 : case Sid::defaultsVersion:
127 0 : score->style().setDefaultStyleVersion(newValue.toInt());
128 0 : break;
129 13 : case Sid::createMultiMeasureRests:
130 13 : if (oldValue.toBool() == true && newValue.toBool() == false) {
131 2 : Transaction& tx = score->transactionManager()->currentOrDummyTransaction();
132 2 : EditSystemLocks::removeSystemLocksContainingMMRests(tx, score);
133 2 : EditPageLocks::removePageLocksContainingMMRests(tx, score);
134 : }
135 13 : break;
136 44 : default:
137 44 : break;
138 : }
139 57 : }
140 :
141 138 : void ChangeStyleValues::flip()
142 : {
143 138 : if (!m_score) {
144 0 : return;
145 : }
146 :
147 138 : bool styleChanged = false;
148 138 : const MStyle& style = m_score->style();
149 :
150 277 : for (auto& pair : m_values) {
151 139 : PropertyValue oldValue = style.styleV(pair.first);
152 139 : if (oldValue == pair.second) {
153 82 : continue;
154 : }
155 :
156 57 : changeStyleValue(m_score, pair.first, oldValue, pair.second);
157 57 : pair.second = oldValue;
158 :
159 57 : styleChanged = true;
160 139 : }
161 :
162 138 : if (styleChanged) {
163 56 : m_score->styleChanged();
164 : }
165 : }
166 :
167 : //---------------------------------------------------------
168 : // EditStyle
169 : //---------------------------------------------------------
170 :
171 0 : bool EditStyle::loadStyle(Transaction& tx, Score* score, muse::io::IODevice& dev, bool ign, bool overlap)
172 : {
173 0 : TRACEFUNC;
174 :
175 0 : if (!dev.open(muse::io::IODevice::ReadOnly)) {
176 0 : LOGE() << "The style data is not available.";
177 0 : return false;
178 : }
179 :
180 0 : bool success = false;
181 0 : MStyle st = score->style();
182 0 : if (st.read(&dev, ign)) {
183 0 : tx.push(new ChangeStyle(score, st, overlap));
184 0 : success = true;
185 : } else {
186 0 : LOGE() << "The style data is not compatible with this version of MuseScore Studio.";
187 : }
188 :
189 0 : dev.close();
190 0 : return success;
191 0 : }
|