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 :
23 : #include "accidental.h"
24 :
25 : #include "types/symnames.h"
26 : #include "types/translatablestring.h"
27 :
28 : #include "actionicon.h"
29 : #include "note.h"
30 : #include "score.h"
31 :
32 : #include "../editing/editnote.h"
33 :
34 : #include "log.h"
35 :
36 : using namespace mu;
37 : using namespace mu::engraving;
38 :
39 : namespace mu::engraving {
40 : //---------------------------------------------------------
41 : // Acc
42 : //---------------------------------------------------------
43 :
44 : struct Acc {
45 : AccidentalVal offset; // semitone offset
46 : double centOffset;
47 : SymId sym;
48 2793 : Acc(AccidentalVal o, double o2, SymId s)
49 2793 : : offset(o), centOffset(o2), sym(s) {}
50 : };
51 :
52 : // NOTE: keep this in sync with AccidentalType enum in types.h, watch out for isMicrotonal()
53 : static const Acc ACC_LIST[] = {
54 : Acc(AccidentalVal::NATURAL, 0, SymId::noSym), // NONE
55 : Acc(AccidentalVal::FLAT, 0, SymId::accidentalFlat), // FLAT
56 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNatural), // NATURAL
57 : Acc(AccidentalVal::SHARP, 0, SymId::accidentalSharp), // SHARP
58 : Acc(AccidentalVal::SHARP2, 0, SymId::accidentalDoubleSharp), // SHARP2
59 : Acc(AccidentalVal::FLAT2, 0, SymId::accidentalDoubleFlat), // FLAT2
60 : Acc(AccidentalVal::SHARP3, 0, SymId::accidentalTripleSharp), // SHARP3
61 : Acc(AccidentalVal::FLAT3, 0, SymId::accidentalTripleFlat), // FLAT3
62 : Acc(AccidentalVal::FLAT, 0, SymId::accidentalNaturalFlat), // NATURAL_FLAT
63 : Acc(AccidentalVal::SHARP, 0, SymId::accidentalNaturalSharp), // NATURAL_SHARP
64 : Acc(AccidentalVal::SHARP2, 0, SymId::accidentalSharpSharp), // SHARP_SHARP
65 :
66 : // Gould arrow quartertone
67 : Acc(AccidentalVal::NATURAL, -50, SymId::accidentalQuarterToneFlatArrowUp), // FLAT_ARROW_UP
68 : Acc(AccidentalVal::NATURAL, -150, SymId::accidentalThreeQuarterTonesFlatArrowDown), // FLAT_ARROW_DOWN
69 : Acc(AccidentalVal::NATURAL, 50, SymId::accidentalQuarterToneSharpNaturalArrowUp), // NATURAL_ARROW_UP
70 : Acc(AccidentalVal::NATURAL, -50, SymId::accidentalQuarterToneFlatNaturalArrowDown), // NATURAL_ARROW_DOWN
71 : Acc(AccidentalVal::NATURAL, 150, SymId::accidentalThreeQuarterTonesSharpArrowUp), // SHARP_ARROW_UP
72 : Acc(AccidentalVal::NATURAL, 50, SymId::accidentalQuarterToneSharpArrowDown), // SHARP_ARROW_DOWN
73 : Acc(AccidentalVal::NATURAL, 250, SymId::accidentalFiveQuarterTonesSharpArrowUp), // SHARP2_ARROW_UP
74 : Acc(AccidentalVal::NATURAL, 150, SymId::accidentalThreeQuarterTonesSharpArrowDown), // SHARP2_ARROW_DOWN
75 : Acc(AccidentalVal::NATURAL, -150, SymId::accidentalThreeQuarterTonesFlatArrowUp), // FLAT2_ARROW_UP
76 : Acc(AccidentalVal::NATURAL, -250, SymId::accidentalFiveQuarterTonesFlatArrowDown), // FLAT2_ARROW_DOWN
77 : Acc(AccidentalVal::NATURAL, -50, SymId::accidentalArrowDown), // ARROW_DOWN
78 : Acc(AccidentalVal::NATURAL, 50, SymId::accidentalArrowUp), // ARROW_UP
79 :
80 : // Stein-Zimmermann
81 : Acc(AccidentalVal::NATURAL, -50, SymId::accidentalQuarterToneFlatStein), // MIRRORED_FLAT
82 : Acc(AccidentalVal::NATURAL, -150, SymId::accidentalThreeQuarterTonesFlatZimmermann), // MIRRORED_FLAT2
83 : Acc(AccidentalVal::NATURAL, 50, SymId::accidentalQuarterToneSharpStein), // SHARP_SLASH
84 : Acc(AccidentalVal::NATURAL, 150, SymId::accidentalThreeQuarterTonesSharpStein), // SHARP_SLASH4
85 :
86 : // Arel-Ezgi-Uzdilek (AEU)
87 : Acc(AccidentalVal::NATURAL, -89, SymId::accidentalBuyukMucennebFlat), // FLAT_SLASH2
88 : Acc(AccidentalVal::NATURAL, -44, SymId::accidentalBakiyeFlat), // FLAT_SLASH
89 : Acc(AccidentalVal::NATURAL, 56, SymId::accidentalKucukMucennebSharp), // SHARP_SLASH3
90 : Acc(AccidentalVal::NATURAL, 89, SymId::accidentalBuyukMucennebSharp), // SHARP_SLASH2
91 :
92 : // Extended Helmholtz-Ellis accidentals (just intonation)
93 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatOneArrowDown),
94 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatOneArrowDown),
95 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalOneArrowDown),
96 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpOneArrowDown),
97 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpOneArrowDown),
98 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatOneArrowUp),
99 :
100 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatOneArrowUp),
101 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalOneArrowUp),
102 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpOneArrowUp),
103 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpOneArrowUp),
104 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatTwoArrowsDown),
105 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatTwoArrowsDown),
106 :
107 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalTwoArrowsDown),
108 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpTwoArrowsDown),
109 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpTwoArrowsDown),
110 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatTwoArrowsUp),
111 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatTwoArrowsUp),
112 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalTwoArrowsUp),
113 :
114 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpTwoArrowsUp),
115 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpTwoArrowsUp),
116 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatThreeArrowsDown),
117 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatThreeArrowsDown),
118 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalThreeArrowsDown),
119 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpThreeArrowsDown),
120 :
121 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpThreeArrowsDown),
122 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatThreeArrowsUp),
123 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatThreeArrowsUp),
124 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalThreeArrowsUp),
125 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpThreeArrowsUp),
126 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpThreeArrowsUp),
127 :
128 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalLowerOneSeptimalComma),
129 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalRaiseOneSeptimalComma),
130 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalLowerTwoSeptimalCommas),
131 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalRaiseTwoSeptimalCommas),
132 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalLowerOneUndecimalQuartertone),
133 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalRaiseOneUndecimalQuartertone),
134 :
135 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalLowerOneTridecimalQuartertone),
136 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalRaiseOneTridecimalQuartertone),
137 :
138 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleFlatEqualTempered),
139 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalFlatEqualTempered),
140 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalNaturalEqualTempered),
141 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalSharpEqualTempered),
142 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalDoubleSharpEqualTempered),
143 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalQuarterFlatEqualTempered),
144 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalQuarterSharpEqualTempered),
145 :
146 : Acc(AccidentalVal::NATURAL, -6.8, SymId::accidentalCombiningLower17Schisma),
147 : Acc(AccidentalVal::NATURAL, 6.8, SymId::accidentalCombiningRaise17Schisma),
148 : Acc(AccidentalVal::NATURAL, -3.4, SymId::accidentalCombiningLower19Schisma),
149 : Acc(AccidentalVal::NATURAL, 3.4, SymId::accidentalCombiningRaise19Schisma),
150 : Acc(AccidentalVal::NATURAL, -16.5, SymId::accidentalCombiningLower23Limit29LimitComma),
151 : Acc(AccidentalVal::NATURAL, 16.5, SymId::accidentalCombiningRaise23Limit29LimitComma),
152 : Acc(AccidentalVal::NATURAL, -1.7, SymId::accidentalCombiningLower31Schisma),
153 : Acc(AccidentalVal::NATURAL, 1.7, SymId::accidentalCombiningRaise31Schisma),
154 : Acc(AccidentalVal::NATURAL, -10.9, SymId::accidentalCombiningLower53LimitComma),
155 : Acc(AccidentalVal::NATURAL, 10.9, SymId::accidentalCombiningRaise53LimitComma),
156 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalEnharmonicAlmostEqualTo),
157 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalEnharmonicEquals),
158 : Acc(AccidentalVal::NATURAL, 0, SymId::accidentalEnharmonicTilde),
159 :
160 : // Persian
161 : Acc(AccidentalVal::NATURAL, 33, SymId::accidentalSori), // SORI
162 : Acc(AccidentalVal::NATURAL, -67, SymId::accidentalKoron), // KORON
163 :
164 : // Wyschnegradsky
165 : Acc(AccidentalVal::NATURAL, -167, SymId::accidentalWyschnegradsky10TwelfthsFlat),
166 : Acc(AccidentalVal::NATURAL, 167, SymId::accidentalWyschnegradsky10TwelfthsSharp),
167 : Acc(AccidentalVal::NATURAL, -183, SymId::accidentalWyschnegradsky11TwelfthsFlat),
168 : Acc(AccidentalVal::NATURAL, 183, SymId::accidentalWyschnegradsky11TwelfthsSharp),
169 : Acc(AccidentalVal::NATURAL, -17, SymId::accidentalWyschnegradsky1TwelfthsFlat),
170 : Acc(AccidentalVal::NATURAL, 17, SymId::accidentalWyschnegradsky1TwelfthsSharp),
171 : Acc(AccidentalVal::NATURAL, -33, SymId::accidentalWyschnegradsky2TwelfthsFlat),
172 : Acc(AccidentalVal::NATURAL, 33, SymId::accidentalWyschnegradsky2TwelfthsSharp),
173 : Acc(AccidentalVal::NATURAL, -50, SymId::accidentalWyschnegradsky3TwelfthsFlat),
174 : Acc(AccidentalVal::NATURAL, 50, SymId::accidentalWyschnegradsky3TwelfthsSharp),
175 : Acc(AccidentalVal::NATURAL, -67, SymId::accidentalWyschnegradsky4TwelfthsFlat),
176 : Acc(AccidentalVal::NATURAL, 67, SymId::accidentalWyschnegradsky4TwelfthsSharp),
177 : Acc(AccidentalVal::NATURAL, -83, SymId::accidentalWyschnegradsky5TwelfthsFlat),
178 : Acc(AccidentalVal::NATURAL, 83, SymId::accidentalWyschnegradsky5TwelfthsSharp),
179 : Acc(AccidentalVal::FLAT, 0, SymId::accidentalWyschnegradsky6TwelfthsFlat),
180 : Acc(AccidentalVal::SHARP, 0, SymId::accidentalWyschnegradsky6TwelfthsSharp),
181 : Acc(AccidentalVal::NATURAL, -117, SymId::accidentalWyschnegradsky7TwelfthsFlat),
182 : Acc(AccidentalVal::NATURAL, 117, SymId::accidentalWyschnegradsky7TwelfthsSharp),
183 : Acc(AccidentalVal::NATURAL, -133, SymId::accidentalWyschnegradsky8TwelfthsFlat),
184 : Acc(AccidentalVal::NATURAL, 133, SymId::accidentalWyschnegradsky8TwelfthsSharp),
185 : Acc(AccidentalVal::NATURAL, -150, SymId::accidentalWyschnegradsky9TwelfthsFlat),
186 : Acc(AccidentalVal::NATURAL, 150, SymId::accidentalWyschnegradsky9TwelfthsSharp),
187 :
188 : // the most important (Spartan) Sagittal accidentals
189 : Acc(AccidentalVal::NATURAL, -17, SymId::accSagittal5v7KleismaDown),
190 : Acc(AccidentalVal::NATURAL, 17, SymId::accSagittal5v7KleismaUp),
191 : Acc(AccidentalVal::NATURAL, -17, SymId::accSagittal5CommaDown),
192 : Acc(AccidentalVal::NATURAL, 17, SymId::accSagittal5CommaUp),
193 : Acc(AccidentalVal::NATURAL, -33, SymId::accSagittal7CommaDown),
194 : Acc(AccidentalVal::NATURAL, 33, SymId::accSagittal7CommaUp),
195 : Acc(AccidentalVal::NATURAL, -33, SymId::accSagittal25SmallDiesisDown),
196 : Acc(AccidentalVal::NATURAL, 33, SymId::accSagittal25SmallDiesisUp),
197 : Acc(AccidentalVal::NATURAL, -50, SymId::accSagittal35MediumDiesisDown),
198 : Acc(AccidentalVal::NATURAL, 50, SymId::accSagittal35MediumDiesisUp),
199 : Acc(AccidentalVal::NATURAL, -50, SymId::accSagittal11MediumDiesisDown),
200 : Acc(AccidentalVal::NATURAL, 50, SymId::accSagittal11MediumDiesisUp),
201 : Acc(AccidentalVal::NATURAL, -50, SymId::accSagittal11LargeDiesisDown),
202 : Acc(AccidentalVal::NATURAL, 50, SymId::accSagittal11LargeDiesisUp),
203 : Acc(AccidentalVal::NATURAL, -50, SymId::accSagittal35LargeDiesisDown),
204 : Acc(AccidentalVal::NATURAL, 50, SymId::accSagittal35LargeDiesisUp),
205 : Acc(AccidentalVal::NATURAL, -67, SymId::accSagittalFlat25SUp),
206 : Acc(AccidentalVal::NATURAL, 67, SymId::accSagittalSharp25SDown),
207 : Acc(AccidentalVal::NATURAL, -67, SymId::accSagittalFlat7CUp),
208 : Acc(AccidentalVal::NATURAL, 67, SymId::accSagittalSharp7CDown),
209 : Acc(AccidentalVal::NATURAL, -83, SymId::accSagittalFlat5CUp),
210 : Acc(AccidentalVal::NATURAL, 83, SymId::accSagittalSharp5CDown),
211 : Acc(AccidentalVal::NATURAL, -83, SymId::accSagittalFlat5v7kUp),
212 : Acc(AccidentalVal::NATURAL, 83, SymId::accSagittalSharp5v7kDown),
213 : Acc(AccidentalVal::NATURAL, -100, SymId::accSagittalFlat),
214 : Acc(AccidentalVal::NATURAL, 100, SymId::accSagittalSharp),
215 :
216 : // Turkish folk music accidentals
217 : Acc(AccidentalVal::NATURAL, -22.2, SymId::accidental1CommaFlat),
218 : Acc(AccidentalVal::NATURAL, 22.2, SymId::accidental1CommaSharp),
219 : Acc(AccidentalVal::NATURAL, -44.4, SymId::accidental2CommaFlat),
220 : Acc(AccidentalVal::NATURAL, 44.4, SymId::accidental2CommaSharp),
221 : Acc(AccidentalVal::NATURAL, -66.7, SymId::accidental3CommaFlat),
222 : Acc(AccidentalVal::NATURAL, 66.7, SymId::accidental3CommaSharp),
223 : Acc(AccidentalVal::NATURAL, -88.9, SymId::accidental4CommaFlat),
224 : //Acc(AccidentalVal::NATURAL, 88.9, SymId::accidentalSharp),
225 : Acc(AccidentalVal::NATURAL, 111.1, SymId::accidental5CommaSharp),
226 : };
227 :
228 : //---------------------------------------------------------
229 : // sym2accidentalVal
230 : //---------------------------------------------------------
231 :
232 100 : AccidentalVal sym2accidentalVal(SymId id)
233 : {
234 1070 : for (const Acc& a : ACC_LIST) {
235 1070 : if (a.sym == id) {
236 100 : return a.offset;
237 : }
238 : }
239 0 : return AccidentalVal::NATURAL;
240 : }
241 :
242 : //---------------------------------------------------------
243 : // Accidental
244 : //---------------------------------------------------------
245 :
246 4941 : Accidental::Accidental(DummyParentOr<EngravingItem> parent)
247 4941 : : EngravingItem(ElementType::ACCIDENTAL, parent, ElementFlag::MOVABLE)
248 : {
249 4941 : }
250 :
251 93596 : Note* Accidental::note() const
252 : {
253 93596 : EngravingObject* owner = ownershipParent();
254 93596 : return owner && owner->isNote() ? toNote(owner) : nullptr;
255 : }
256 :
257 : //---------------------------------------------------------
258 : // subTypeUserName
259 : //---------------------------------------------------------
260 :
261 0 : TranslatableString Accidental::subtypeUserName() const
262 : {
263 0 : return SymNames::userNameForSymId(symId());
264 : }
265 :
266 : //---------------------------------------------------------
267 : // symbol
268 : //---------------------------------------------------------
269 :
270 12036 : SymId Accidental::symId() const
271 : {
272 12036 : return ACC_LIST[int(accidentalType())].sym;
273 : }
274 :
275 114 : bool Accidental::parentNoteHasParentheses() const
276 : {
277 114 : const EngravingObject* owner = ownershipParent();
278 114 : return owner && owner->isNote() && toNote(owner)->parenthesisInfo();
279 : }
280 :
281 : //---------------------------------------------------------
282 : // subtype2value
283 : // returns the resulting pitch offset
284 : //---------------------------------------------------------
285 :
286 1965 : AccidentalVal Accidental::subtype2value(AccidentalType st)
287 : {
288 1965 : return ACC_LIST[int(st)].offset;
289 : }
290 :
291 : //---------------------------------------------------------
292 : // subtype2name
293 : //---------------------------------------------------------
294 :
295 2618 : AsciiStringView Accidental::subtype2name(AccidentalType st)
296 : {
297 2618 : return SymNames::nameForSymId(ACC_LIST[int(st)].sym);
298 : }
299 :
300 : //---------------------------------------------------------
301 : // subtype2symbol
302 : //---------------------------------------------------------
303 :
304 0 : SymId Accidental::subtype2symbol(AccidentalType st)
305 : {
306 0 : return ACC_LIST[int(st)].sym;
307 : }
308 :
309 : //---------------------------------------------------------
310 : // subtype2centoffset
311 : //---------------------------------------------------------
312 :
313 13585 : double Accidental::subtype2centOffset(AccidentalType st)
314 : {
315 13585 : return ACC_LIST[int(st)].centOffset;
316 : }
317 :
318 0 : AccidentalType Accidental::centOffset2Subtype(double centOffset)
319 : {
320 0 : for (int i = 0; i < static_cast<int>(AccidentalType::END); ++i) {
321 0 : if (muse::RealIsEqual(ACC_LIST[i].centOffset, centOffset)) {
322 0 : return static_cast<AccidentalType>(i);
323 : }
324 : }
325 :
326 0 : return AccidentalType::NONE;
327 : }
328 :
329 237 : AccidentalType Accidental::value2MicrotonalSubtype(AccidentalVal val, int quarterOff)
330 : {
331 237 : if (quarterOff == 0) {
332 225 : return value2subtype(val);
333 : }
334 :
335 12 : if (quarterOff < -1 || quarterOff > 1) {
336 : // TODO: more general implementation
337 0 : return value2subtype(val);
338 : }
339 :
340 12 : switch (val) {
341 9 : case AccidentalVal::NATURAL:
342 9 : return quarterOff == 1 ? AccidentalType::SHARP_ARROW_DOWN : AccidentalType::FLAT_ARROW_UP;
343 2 : case AccidentalVal::FLAT:
344 2 : return quarterOff == 1 ? AccidentalType::FLAT_ARROW_UP : AccidentalType::FLAT_ARROW_DOWN;
345 1 : case AccidentalVal::SHARP:
346 1 : return quarterOff == 1 ? AccidentalType::SHARP_ARROW_UP : AccidentalType::SHARP_ARROW_DOWN;
347 0 : case AccidentalVal::FLAT2:
348 0 : return quarterOff == 1 ? AccidentalType::FLAT2_ARROW_UP : AccidentalType::FLAT2_ARROW_DOWN;
349 0 : case AccidentalVal::SHARP2:
350 0 : return quarterOff == 1 ? AccidentalType::SHARP2_ARROW_UP : AccidentalType::SHARP2_ARROW_DOWN;
351 0 : default:
352 0 : return value2subtype(val);
353 : }
354 : }
355 :
356 30548 : int Accidental::line() const
357 : {
358 30548 : Note* n = note();
359 30548 : return n ? n->line() : 0;
360 : }
361 :
362 : //---------------------------------------------------------
363 : // name2subtype
364 : //---------------------------------------------------------
365 :
366 703 : AccidentalType Accidental::name2subtype(const AsciiStringView& tag)
367 : {
368 703 : SymId symId = SymNames::symIdByName(tag);
369 703 : if (symId == SymId::noSym) {
370 : // LOGD("no symbol found");
371 : } else {
372 703 : int i = 0;
373 2604 : for (const Acc& acc : ACC_LIST) {
374 2604 : if (acc.sym == symId) {
375 703 : return AccidentalType(i);
376 : }
377 1901 : ++i;
378 : }
379 : }
380 0 : return AccidentalType::NONE;
381 : }
382 :
383 : //---------------------------------------------------------
384 : // setSubtype
385 : //---------------------------------------------------------
386 :
387 703 : void Accidental::setSubtype(const AsciiStringView& tag)
388 : {
389 703 : setAccidentalType(name2subtype(tag));
390 703 : }
391 :
392 5118 : void Accidental::setAccidentalType(AccidentalType t)
393 : {
394 5118 : m_accidentalType = t;
395 5118 : if (note()) {
396 4787 : note()->setCentOffset(Accidental::subtype2centOffset(t));
397 : }
398 5118 : }
399 :
400 4082 : void Accidental::computeMag()
401 : {
402 4082 : double m = layoutParent() ? layoutParent()->mag() : 1.0;
403 4082 : if (isSmall()) {
404 2 : m *= style().styleD(Sid::smallNoteMag);
405 : }
406 4082 : mutldata()->setMag(m);
407 4082 : }
408 :
409 : //---------------------------------------------------------
410 : // value2subtype
411 : //---------------------------------------------------------
412 :
413 4171 : AccidentalType Accidental::value2subtype(AccidentalVal v)
414 : {
415 4171 : switch (v) {
416 917 : case AccidentalVal::NATURAL: return AccidentalType::NONE;
417 2169 : case AccidentalVal::SHARP: return AccidentalType::SHARP;
418 183 : case AccidentalVal::SHARP2: return AccidentalType::SHARP2;
419 4 : case AccidentalVal::SHARP3: return AccidentalType::SHARP3;
420 820 : case AccidentalVal::FLAT: return AccidentalType::FLAT;
421 74 : case AccidentalVal::FLAT2: return AccidentalType::FLAT2;
422 4 : case AccidentalVal::FLAT3: return AccidentalType::FLAT3;
423 0 : default:
424 0 : ASSERT_X(u"value2subtype: illegal accidental val: " + String::number(int(v)));
425 : }
426 : return AccidentalType::NONE;
427 : }
428 :
429 : //---------------------------------------------------------
430 : // acceptDrop
431 : //---------------------------------------------------------
432 :
433 0 : bool Accidental::acceptDrop(EditData& data) const
434 : {
435 0 : const EngravingItem* e = data.dropElement;
436 :
437 0 : if (e->isAccidental()) {
438 0 : return note();
439 : }
440 :
441 0 : if (e->isActionIcon()) {
442 0 : ActionIconType type = toActionIcon(e)->actionType();
443 : return type == ActionIconType::PARENTHESES
444 0 : || type == ActionIconType::BRACKETS;
445 : }
446 :
447 0 : return false;
448 : }
449 :
450 : //---------------------------------------------------------
451 : // drop
452 : //---------------------------------------------------------
453 :
454 0 : EngravingItem* Accidental::drop(Transaction&, EditData& data)
455 : {
456 0 : EngravingItem* e = data.dropElement;
457 0 : switch (e->type()) {
458 0 : case ElementType::ACCIDENTAL:
459 0 : EditNote::changeAccidental(score(), note(), toAccidental(e)->accidentalType());
460 0 : break;
461 0 : case ElementType::ACTION_ICON:
462 0 : switch (toActionIcon(e)->actionType()) {
463 0 : case ActionIconType::PARENTHESES:
464 0 : undoChangeProperty(Pid::ACCIDENTAL_BRACKET, int(AccidentalBracket::PARENTHESIS), PropertyFlags::NOSTYLE);
465 0 : break;
466 0 : case ActionIconType::BRACKETS:
467 0 : undoChangeProperty(Pid::ACCIDENTAL_BRACKET, int(AccidentalBracket::BRACKET), PropertyFlags::NOSTYLE);
468 0 : break;
469 0 : default:
470 0 : LOGD("unknown icon type");
471 0 : break;
472 : }
473 0 : break;
474 0 : default:
475 0 : break;
476 : }
477 0 : delete e;
478 0 : return nullptr;
479 : }
480 :
481 : //---------------------------------------------------------
482 : // getProperty
483 : //---------------------------------------------------------
484 :
485 36951 : PropertyValue Accidental::getProperty(Pid propertyId) const
486 : {
487 36951 : switch (propertyId) {
488 2618 : case Pid::ACCIDENTAL_TYPE: return int(m_accidentalType);
489 2618 : case Pid::SMALL: return m_isSmall;
490 2618 : case Pid::ACCIDENTAL_BRACKET: return int(bracket());
491 2618 : case Pid::ACCIDENTAL_ROLE: return role();
492 2618 : case Pid::ACCIDENTAL_STACKING_ORDER_OFFSET: return stackingOrderOffset();
493 23861 : default:
494 23861 : return EngravingItem::getProperty(propertyId);
495 : }
496 : }
497 :
498 : //---------------------------------------------------------
499 : // propertyDefault
500 : //---------------------------------------------------------
501 :
502 36652 : PropertyValue Accidental::propertyDefault(Pid propertyId) const
503 : {
504 36652 : switch (propertyId) {
505 2618 : case Pid::ACCIDENTAL_TYPE: return int(AccidentalType::NONE);
506 2618 : case Pid::SMALL: return false;
507 2618 : case Pid::ACCIDENTAL_BRACKET: return int(AccidentalBracket::NONE);
508 5236 : case Pid::ACCIDENTAL_ROLE: return AccidentalRole::AUTO;
509 2618 : case Pid::ACCIDENTAL_STACKING_ORDER_OFFSET: return 0;
510 23562 : default:
511 23562 : return EngravingItem::propertyDefault(propertyId);
512 : }
513 : }
514 :
515 : //---------------------------------------------------------
516 : // setProperty
517 : //---------------------------------------------------------
518 :
519 32 : bool Accidental::setProperty(Pid propertyId, const PropertyValue& v)
520 : {
521 32 : switch (propertyId) {
522 0 : case Pid::ACCIDENTAL_TYPE:
523 0 : setAccidentalType(AccidentalType(v.toInt()));
524 0 : break;
525 0 : case Pid::SMALL:
526 0 : m_isSmall = v.toBool();
527 0 : break;
528 0 : case Pid::ACCIDENTAL_BRACKET:
529 0 : m_bracket = AccidentalBracket(v.toInt());
530 0 : break;
531 0 : case Pid::ACCIDENTAL_ROLE:
532 0 : m_role = v.value<AccidentalRole>();
533 0 : break;
534 0 : case Pid::ACCIDENTAL_STACKING_ORDER_OFFSET:
535 0 : setStackingOrderOffset(v.toInt());
536 0 : break;
537 32 : default:
538 32 : return EngravingItem::setProperty(propertyId, v);
539 : }
540 0 : triggerLayout();
541 0 : return true;
542 : }
543 :
544 : //---------------------------------------------------------
545 : // accessibleInfo
546 : //---------------------------------------------------------
547 :
548 0 : String Accidental::accessibleInfo() const
549 : {
550 0 : return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), translatedSubtypeUserName());
551 : }
552 : }
|