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 : #include "notationconfiguration.h"
23 :
24 : #include "engraving/dom/mscore.h"
25 :
26 : #include "io/path.h"
27 : #include "settings.h"
28 :
29 : #include "notationtypes.h"
30 :
31 : using namespace mu;
32 : using namespace mu::notation;
33 : using namespace muse;
34 : using namespace muse::async;
35 : using namespace muse::draw;
36 : using namespace muse::ui;
37 :
38 : static const std::string module_name("notation");
39 :
40 : static const Settings::Key LIGHT_SCORE_BACKGROUND_COLOR(module_name, "ui/canvas/background/lightTheme_score_background_color");
41 : static const Settings::Key DARK_SCORE_BACKGROUND_COLOR(module_name, "ui/canvas/background/darkTheme_score_background_color");
42 : static const Settings::Key HC_BLACK_SCORE_BACKGROUND_COLOR(module_name, "ui/canvas/background/hc_black_score_background_color");
43 : static const Settings::Key HC_WHITE_SCORE_BACKGROUND_COLOR(module_name, "ui/canvas/background/hc_white_score_background_color");
44 : static const Settings::Key BACKGROUND_WALLPAPER_PATH(module_name, "ui/canvas/background/wallpaper");
45 : static const Settings::Key BACKGROUND_USE_COLOR(module_name, "ui/canvas/background/useColor");
46 :
47 : static const Settings::Key FOREGROUND_COLOR(module_name, "ui/canvas/foreground/color");
48 : static const Settings::Key INVERTED_FOREGROUND_COLOR(module_name, "ui/canvas/foreground/invertedColor");
49 : static const Settings::Key FOREGROUND_WALLPAPER_PATH(module_name, "ui/canvas/foreground/wallpaper");
50 : static const Settings::Key FOREGROUND_USE_COLOR(module_name, "ui/canvas/foreground/useColor");
51 :
52 : // TODO(5.0): replace "engraving" with module_name
53 : static const Settings::Key INVERT_SCORE_COLOR("engraving", "engraving/scoreColorInversion");
54 : static const Settings::Key ONLY_INVERT_IN_DARK_THEME(module_name, "ui/canvas/onlyInvertInDarkTheme");
55 :
56 : static const Settings::Key NOTE_INPUT_PREVIEW_COLOR(module_name, "ui/canvas/noteInputPreviewColor");
57 :
58 : static const Settings::Key USE_NOTE_INPUT_CURSOR_IN_INPUT_BY_DURATION(module_name,
59 : "ui/canvas/useNoteInputCursorInInputByDuration");
60 :
61 : static const Settings::Key THIN_NOTE_INPUT_CURSOR(module_name, "ui/canvas/thinNoteInputCursor");
62 :
63 : static const Settings::Key SELECTION_PROXIMITY(module_name, "ui/canvas/misc/selectionProximity");
64 :
65 : static const Settings::Key DEFAULT_ZOOM_TYPE(module_name, "ui/canvas/zoomDefaultType");
66 : static const Settings::Key DEFAULT_ZOOM(module_name, "ui/canvas/zoomDefaultLevel");
67 : static const Settings::Key KEYBOARD_ZOOM_PRECISION(module_name, "ui/canvas/zoomPrecisionKeyboard");
68 : static const Settings::Key MOUSE_ZOOM_PRECISION(module_name, "ui/canvas/zoomPrecisionMouse");
69 :
70 : static const Settings::Key CURRENT_AUTOMATION_TYPE(module_name, "notation/automation/currentType");
71 :
72 : static const Settings::Key USER_STYLES_PATH(module_name, "application/paths/myStyles");
73 : static const Settings::Key USER_MUSIC_FONTS_PATH(module_name, "application/paths/myMusicFonts");
74 :
75 : static const Settings::Key DEFAULT_NOTE_INPUT_METHOD(module_name, "score/defaultInputMethod");
76 :
77 : static const Settings::Key ADD_ACCIDENTAL_ARTICULATIONS_DOTS_TO_NEXT_NOTE_ENTERED(module_name,
78 : "score/addAccidentalDotsArticulationsToNextNoteEntered");
79 :
80 : static const Settings::Key IS_MIDI_INPUT_ENABLED(module_name, "io/midi/enableInput");
81 : static const Settings::Key START_NOTE_INPUT_AT_SELECTED_NOTE_REST_WHEN_PRESSING_MIDI_KEY(module_name,
82 : "score/startNoteInputAtSelectionWhenPressingMidiKey");
83 : static const Settings::Key USE_MIDI_INPUT_WRITTEN_PITCH(module_name, "io/midi/useWrittenPitch");
84 : static const Settings::Key IS_AUTOMATICALLY_PAN_ENABLED(module_name, "application/playback/panPlayback");
85 : static const Settings::Key IS_PLAY_REPEATS_ENABLED(module_name, "application/playback/playRepeats");
86 : static const Settings::Key IS_PLAY_CHORD_SYMBOLS_ENABLED(module_name, "application/playback/playChordSymbols");
87 : static const Settings::Key IS_PLAY_PREVIEW_NOTES_IN_INPUT_BY_DURATION_ENABLED(module_name,
88 : "application/playback/playPreviewNotesInInputByDuration");
89 : static const Settings::Key PLAY_PREVIEW_NOTES_WITH_SCORE_DYNAMICS(module_name, "application/playback/playPreviewNotesWithScoreDynamics");
90 : static const Settings::Key IS_METRONOME_ENABLED(module_name, "application/playback/metronomeEnabled");
91 : static const Settings::Key IS_COUNT_IN_ENABLED(module_name, "application/playback/countInEnabled");
92 :
93 : static const Settings::Key IS_CANVAS_ORIENTATION_VERTICAL_KEY(module_name, "ui/canvas/scroll/verticalOrientation");
94 :
95 : static const Settings::Key COLOR_NOTES_OUTSIDE_OF_USABLE_PITCH_RANGE(module_name, "score/note/warnPitchRange");
96 : static const Settings::Key WARN_GUITAR_BENDS(module_name, "score/note/warnGuitarBends");
97 : static const Settings::Key REALTIME_DELAY(module_name, "io/midi/realtimeDelay");
98 : static const Settings::Key USE_MIDI_VELOCITY_AND_DURATION_DURING_NOTE_INPUT(module_name,
99 : "io/midi/useMidiVelocityAndDurationDuringNoteInput");
100 : static const Settings::Key NOTE_DEFAULT_PLAY_DURATION(module_name, "score/note/defaultPlayDuration");
101 :
102 : static const Settings::Key USER_INSTRUMENTS_PATH(module_name, "application/paths/userInstruments");
103 :
104 : static const Settings::Key IS_SNAPPED_TO_VERTICAL_GRID_KEY(module_name, "ui/application/raster/isSnappedToVerticalGrid");
105 : static const Settings::Key IS_SNAPPED_TO_HORIZONTAL_GRID_KEY(module_name, "ui/application/raster/isSnappedToHorizontalGrid");
106 : static const Settings::Key HORIZONTAL_GRID_SIZE_KEY(module_name, "ui/application/raster/horizontal");
107 : static const Settings::Key VERTICAL_GRID_SIZE_KEY(module_name, "ui/application/raster/vertical");
108 :
109 : static const Settings::Key STYLE_FILE_IMPORT_PATH_KEY(module_name, "import/style/styleFile");
110 :
111 : static constexpr int DEFAULT_GRID_SIZE_SPATIUM = 2;
112 :
113 : static const std::string BY_NOTE_NAME_INPUT_METHOD("BY_NOTE_NAME");
114 :
115 : static const std::map<NoteInputMethod, std::string> NOTE_INPUT_METHOD_TO_STR {
116 : { NoteInputMethod::BY_NOTE_NAME, BY_NOTE_NAME_INPUT_METHOD },
117 : { NoteInputMethod::BY_DURATION, "BY_DURATION" },
118 : { NoteInputMethod::REPITCH, "REPITCH" },
119 : { NoteInputMethod::RHYTHM, "RHYTHM" },
120 : { NoteInputMethod::REALTIME_AUTO, "REALTIME_AUTO" },
121 : { NoteInputMethod::REALTIME_MANUAL, "REALTIME_MANUAL" },
122 : { NoteInputMethod::TIMEWISE, "TIMEWISE" },
123 : };
124 :
125 0 : void NotationConfiguration::init()
126 : {
127 0 : engravingConfiguration()->displayedDefaultColorChanged().onReceive(this, [this](bool inverted, const Color&) {
128 0 : if (inverted == shouldInvertScore()) {
129 0 : m_notationColorChanged.notify();
130 : }
131 0 : });
132 :
133 0 : settings()->setDefaultValue(BACKGROUND_USE_COLOR, Val(true));
134 0 : settings()->valueChanged(BACKGROUND_USE_COLOR).onReceive(nullptr, [this](const Val&) {
135 0 : m_backgroundChanged.notify();
136 0 : });
137 :
138 0 : if (uiConfiguration()) {
139 0 : uiConfiguration()->currentThemeChanged().onNotify(this, [this]() {
140 0 : m_backgroundChanged.notify();
141 0 : if (scoreInversionEnabled() && isOnlyInvertInDarkTheme()) {
142 0 : m_foregroundChanged.notify();
143 0 : m_notationColorChanged.notify();
144 : }
145 0 : });
146 : }
147 :
148 0 : settings()->setDefaultValue(LIGHT_SCORE_BACKGROUND_COLOR, Val(QColor("#BCC1CC")));
149 0 : settings()->valueChanged(LIGHT_SCORE_BACKGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
150 0 : m_backgroundChanged.notify();
151 0 : });
152 :
153 0 : settings()->setDefaultValue(DARK_SCORE_BACKGROUND_COLOR, Val(QColor("#27272B")));
154 0 : settings()->valueChanged(DARK_SCORE_BACKGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
155 0 : m_backgroundChanged.notify();
156 0 : });
157 :
158 0 : settings()->setDefaultValue(HC_BLACK_SCORE_BACKGROUND_COLOR, Val(QColor("#000000")));
159 0 : settings()->valueChanged(HC_BLACK_SCORE_BACKGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
160 0 : m_backgroundChanged.notify();
161 0 : });
162 :
163 0 : settings()->setDefaultValue(HC_WHITE_SCORE_BACKGROUND_COLOR, Val(QColor("#000000")));
164 0 : settings()->valueChanged(HC_WHITE_SCORE_BACKGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
165 0 : m_backgroundChanged.notify();
166 0 : });
167 :
168 0 : settings()->setDefaultValue(BACKGROUND_WALLPAPER_PATH, Val());
169 0 : settings()->valueChanged(BACKGROUND_WALLPAPER_PATH).onReceive(nullptr, [this](const Val&) {
170 0 : m_backgroundChanged.notify();
171 0 : });
172 :
173 0 : settings()->setDefaultValue(FOREGROUND_USE_COLOR, Val(true));
174 0 : settings()->valueChanged(FOREGROUND_USE_COLOR).onReceive(nullptr, [this](const Val&) {
175 0 : m_foregroundChanged.notify();
176 0 : });
177 :
178 0 : settings()->setDefaultValue(FOREGROUND_COLOR, Val(QColor("#f9f9f9")));
179 0 : settings()->valueChanged(FOREGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
180 0 : m_foregroundChanged.notify();
181 0 : });
182 :
183 0 : settings()->setDefaultValue(INVERTED_FOREGROUND_COLOR, Val(QColor("#141416")));
184 0 : settings()->valueChanged(INVERTED_FOREGROUND_COLOR).onReceive(nullptr, [this](const Val&) {
185 0 : m_foregroundChanged.notify();
186 0 : });
187 :
188 0 : settings()->setDefaultValue(INVERT_SCORE_COLOR, Val(false));
189 0 : settings()->valueChanged(INVERT_SCORE_COLOR).onReceive(nullptr, [this](const Val&) {
190 0 : m_scoreInversionChanged.notify();
191 0 : m_foregroundChanged.notify();
192 0 : m_notationColorChanged.notify();
193 0 : });
194 :
195 0 : settings()->setDefaultValue(ONLY_INVERT_IN_DARK_THEME, Val(false));
196 0 : settings()->valueChanged(ONLY_INVERT_IN_DARK_THEME).onReceive(nullptr, [this](const Val&) {
197 0 : m_isOnlyInvertInDarkThemeChanged.notify();
198 0 : if (scoreInversionEnabled()) {
199 0 : m_foregroundChanged.notify();
200 0 : m_notationColorChanged.notify();
201 : }
202 0 : });
203 :
204 0 : settings()->setDefaultValue(NOTE_INPUT_PREVIEW_COLOR, Val(selectionColor()));
205 0 : settings()->setCanBeManuallyEdited(NOTE_INPUT_PREVIEW_COLOR, true);
206 0 : settings()->setDescription(NOTE_INPUT_PREVIEW_COLOR, muse::trc("notation", "Note input preview note color"));
207 :
208 0 : settings()->setDefaultValue(USE_NOTE_INPUT_CURSOR_IN_INPUT_BY_DURATION, Val(false));
209 0 : settings()->valueChanged(USE_NOTE_INPUT_CURSOR_IN_INPUT_BY_DURATION).onReceive(nullptr, [this](const Val&) {
210 0 : m_useNoteInputCursorInInputByDurationChanged.notify();
211 0 : });
212 :
213 0 : settings()->setDefaultValue(THIN_NOTE_INPUT_CURSOR, Val(false)); // accessible via DevTools/Settings
214 :
215 0 : settings()->setDefaultValue(FOREGROUND_WALLPAPER_PATH, Val());
216 0 : settings()->valueChanged(FOREGROUND_WALLPAPER_PATH).onReceive(nullptr, [this](const Val&) {
217 0 : m_foregroundChanged.notify();
218 0 : });
219 :
220 0 : settings()->setDefaultValue(DEFAULT_ZOOM_TYPE, Val(ZoomType::Percentage));
221 0 : settings()->valueChanged(DEFAULT_ZOOM_TYPE).onReceive(this, [this](const Val&) {
222 0 : m_defaultZoomChanged.notify();
223 0 : });
224 0 : settings()->setDefaultValue(DEFAULT_ZOOM, Val(100));
225 0 : settings()->valueChanged(DEFAULT_ZOOM).onReceive(this, [this](const Val&) {
226 0 : m_defaultZoomChanged.notify();
227 0 : });
228 0 : settings()->setDefaultValue(KEYBOARD_ZOOM_PRECISION, Val(2));
229 0 : settings()->setDefaultValue(MOUSE_ZOOM_PRECISION, Val(6));
230 0 : settings()->valueChanged(MOUSE_ZOOM_PRECISION).onReceive(this, [this](const Val&) {
231 0 : m_mouseZoomPrecisionChanged.notify();
232 0 : });
233 :
234 0 : settings()->setDefaultValue(CURRENT_AUTOMATION_TYPE, Val(engraving::AutomationType::Dynamics));
235 0 : settings()->valueChanged(CURRENT_AUTOMATION_TYPE).onReceive(this, [this](const Val&) {
236 0 : m_currentAutomationTypeChanged.notify();
237 0 : });
238 :
239 0 : settings()->setDefaultValue(USER_STYLES_PATH, Val(globalConfiguration()->userDataPath() + "/Styles"));
240 0 : settings()->valueChanged(USER_STYLES_PATH).onReceive(nullptr, [this](const Val& val) {
241 0 : m_userStylesPathChanged.send(val.toPath());
242 0 : });
243 :
244 0 : if (!userStylesPath().empty()) {
245 0 : fileSystem()->makePath(userStylesPath());
246 :
247 : #if !defined(Q_OS_LINUX)
248 : // Create shortcut or symlink to global styles folder. Doesn't overwrite an existing file
249 : // or link, which means it won't work on Linux because the global styles folder is inside
250 : // the AppImage, and the AppImage mountpoint changes on each run. TODO: Check for existing
251 : // link, read it, and if necessary update it. This would make it work on Linux too.
252 : fileSystem()->makeLink(
253 : globalConfiguration()->appDataPath() + "/styles",
254 : userStylesPath() + "/Built-in styles"
255 : );
256 : #endif
257 : }
258 :
259 0 : settings()->setDefaultValue(USER_MUSIC_FONTS_PATH, Val(io::path_t {}));
260 0 : settings()->valueChanged(USER_MUSIC_FONTS_PATH).onReceive(this, [this](const Val& val) {
261 0 : m_userMusicFontsPathChanged.send(val.toString());
262 0 : });
263 :
264 0 : settings()->setDefaultValue(DEFAULT_NOTE_INPUT_METHOD, Val(BY_NOTE_NAME_INPUT_METHOD));
265 0 : settings()->valueChanged(DEFAULT_NOTE_INPUT_METHOD).onReceive(this, [this](const Val&) {
266 0 : m_defaultNoteInputMethodChanged.notify();
267 0 : });
268 :
269 0 : settings()->setDefaultValue(ADD_ACCIDENTAL_ARTICULATIONS_DOTS_TO_NEXT_NOTE_ENTERED, Val(true));
270 0 : settings()->valueChanged(ADD_ACCIDENTAL_ARTICULATIONS_DOTS_TO_NEXT_NOTE_ENTERED).onReceive(this, [this](const Val&) {
271 0 : m_addAccidentalDotsArticulationsToNextNoteEnteredChanged.notify();
272 0 : });
273 :
274 0 : settings()->setDefaultValue(SELECTION_PROXIMITY, Val(2));
275 0 : settings()->valueChanged(SELECTION_PROXIMITY).onReceive(this, [this](const Val& val) {
276 0 : m_selectionProximityChanged.send(val.toInt());
277 0 : });
278 :
279 0 : settings()->setDefaultValue(IS_MIDI_INPUT_ENABLED, Val(true));
280 0 : settings()->valueChanged(IS_MIDI_INPUT_ENABLED).onReceive(this, [this](const Val&) {
281 0 : m_isMidiInputEnabledChanged.notify();
282 0 : });
283 :
284 0 : settings()->setDefaultValue(START_NOTE_INPUT_AT_SELECTED_NOTE_REST_WHEN_PRESSING_MIDI_KEY, Val(true));
285 0 : settings()->valueChanged(START_NOTE_INPUT_AT_SELECTED_NOTE_REST_WHEN_PRESSING_MIDI_KEY).onReceive(this, [this](const Val&) {
286 0 : m_startNoteInputAtSelectedNoteRestWhenPressingMidiKeyChanged.notify();
287 0 : });
288 :
289 0 : settings()->setDefaultValue(IS_AUTOMATICALLY_PAN_ENABLED, Val(true));
290 0 : settings()->valueChanged(IS_AUTOMATICALLY_PAN_ENABLED).onReceive(this, [this](const Val&) {
291 0 : m_isAutomaticallyPanEnabledChanged.notify();
292 0 : });
293 :
294 0 : settings()->setDefaultValue(IS_PLAY_REPEATS_ENABLED, Val(true));
295 :
296 0 : settings()->setDefaultValue(IS_METRONOME_ENABLED, Val(false));
297 0 : settings()->valueChanged(IS_METRONOME_ENABLED).onReceive(this, [this](const Val&) {
298 0 : m_isMetronomeEnabledChanged.notify();
299 0 : });
300 :
301 0 : settings()->setDefaultValue(IS_COUNT_IN_ENABLED, Val(false));
302 0 : settings()->valueChanged(IS_COUNT_IN_ENABLED).onReceive(this, [this](const Val&) {
303 0 : m_isCountInEnabledChanged.notify();
304 0 : });
305 :
306 0 : settings()->setDefaultValue(IS_PLAY_CHORD_SYMBOLS_ENABLED, Val(true));
307 0 : settings()->valueChanged(IS_PLAY_CHORD_SYMBOLS_ENABLED).onReceive(nullptr, [this](const Val&) {
308 0 : m_isPlayChordSymbolsChanged.notify();
309 0 : });
310 :
311 0 : settings()->setDefaultValue(IS_PLAY_PREVIEW_NOTES_IN_INPUT_BY_DURATION_ENABLED, Val(true));
312 0 : settings()->valueChanged(IS_PLAY_PREVIEW_NOTES_IN_INPUT_BY_DURATION_ENABLED).onReceive(nullptr, [this](const Val&) {
313 0 : m_isPlayNotesPreviewInInputByDurationChanged.notify();
314 0 : });
315 :
316 0 : settings()->setDefaultValue(PLAY_PREVIEW_NOTES_WITH_SCORE_DYNAMICS, Val(true));
317 0 : settings()->valueChanged(PLAY_PREVIEW_NOTES_WITH_SCORE_DYNAMICS).onReceive(nullptr, [this](const Val&) {
318 0 : m_playPreviewNotesWithScoreDynamicsChanged.notify();
319 0 : });
320 :
321 0 : settings()->setDefaultValue(IS_CANVAS_ORIENTATION_VERTICAL_KEY, Val(false));
322 0 : settings()->valueChanged(IS_CANVAS_ORIENTATION_VERTICAL_KEY).onReceive(nullptr, [this](const Val&) {
323 0 : m_canvasOrientationChanged.send(canvasOrientation().val);
324 0 : });
325 :
326 0 : settings()->setDefaultValue(COLOR_NOTES_OUTSIDE_OF_USABLE_PITCH_RANGE, Val(true));
327 0 : settings()->valueChanged(COLOR_NOTES_OUTSIDE_OF_USABLE_PITCH_RANGE).onReceive(this, [this](const Val& val) {
328 0 : m_colorNotesOutsideOfUsablePitchRangeChanged.send(val.toBool());
329 0 : });
330 0 : settings()->setDefaultValue(WARN_GUITAR_BENDS, Val(true));
331 0 : settings()->valueChanged(WARN_GUITAR_BENDS).onReceive(this, [this](const Val& val) {
332 0 : m_warnGuitarBendsChanged.send(val.toBool());
333 0 : });
334 0 : settings()->setDefaultValue(REALTIME_DELAY, Val(750));
335 0 : settings()->valueChanged(REALTIME_DELAY).onReceive(this, [this](const Val& val) {
336 0 : m_delayBetweenNotesInRealTimeModeMillisecondsChanged.send(val.toInt());
337 0 : });
338 :
339 0 : settings()->setDefaultValue(USE_MIDI_VELOCITY_AND_DURATION_DURING_NOTE_INPUT, Val(true));
340 0 : settings()->valueChanged(USE_MIDI_VELOCITY_AND_DURATION_DURING_NOTE_INPUT).onReceive(this, [this](const Val& val) {
341 0 : m_useMidiVelocityAndDurationDuringNoteInputChanged.send(val.toBool());
342 0 : });
343 :
344 0 : settings()->setDefaultValue(NOTE_DEFAULT_PLAY_DURATION, Val(500));
345 0 : settings()->valueChanged(NOTE_DEFAULT_PLAY_DURATION).onReceive(this, [this](const Val& val) {
346 0 : m_notePlayDurationMillisecondsChanged.send(val.toInt());
347 0 : });
348 :
349 0 : settings()->setDefaultValue(STYLE_FILE_IMPORT_PATH_KEY, Val(""));
350 0 : settings()->valueChanged(STYLE_FILE_IMPORT_PATH_KEY).onReceive(this, [this](const Val& val) {
351 0 : m_styleFileImportPathChanged.send(val.toString());
352 0 : });
353 :
354 0 : settings()->setDefaultValue(USER_INSTRUMENTS_PATH, Val(""));
355 0 : settings()->valueChanged(USER_INSTRUMENTS_PATH).onReceive(nullptr, [this](const Val& val) {
356 0 : m_userInstrumentsFolderChanged.send(val.toPath());
357 0 : });
358 :
359 0 : settings()->setDefaultValue(HORIZONTAL_GRID_SIZE_KEY, Val(DEFAULT_GRID_SIZE_SPATIUM));
360 0 : settings()->setDefaultValue(VERTICAL_GRID_SIZE_KEY, Val(DEFAULT_GRID_SIZE_SPATIUM));
361 :
362 0 : settings()->setDefaultValue(USE_MIDI_INPUT_WRITTEN_PITCH, Val(true));
363 0 : m_midiInputUseWrittenPitch.val = settings()->value(USE_MIDI_INPUT_WRITTEN_PITCH).toBool();
364 0 : settings()->valueChanged(USE_MIDI_INPUT_WRITTEN_PITCH).onReceive(this, [this](const Val& val) {
365 0 : m_midiInputUseWrittenPitch.set(val.toBool());
366 0 : });
367 :
368 0 : mu::engraving::MScore::warnPitchRange = colorNotesOutsideOfUsablePitchRange();
369 0 : mu::engraving::MScore::warnGuitarBends = warnGuitarBends();
370 :
371 : // Restore stored grid size values
372 0 : mu::engraving::MScore::setHRaster(settings()->value(HORIZONTAL_GRID_SIZE_KEY).toInt());
373 0 : mu::engraving::MScore::setVRaster(settings()->value(VERTICAL_GRID_SIZE_KEY).toInt());
374 0 : }
375 :
376 0 : QColor NotationConfiguration::notationColor() const
377 : {
378 0 : return engravingConfiguration()->displayedDefaultColor(shouldInvertScore()).toQColor();
379 : }
380 :
381 0 : void NotationConfiguration::setNotationColor(const QColor& color)
382 : {
383 0 : engravingConfiguration()->setDisplayedDefaultColor(color, shouldInvertScore());
384 0 : }
385 :
386 0 : muse::async::Notification NotationConfiguration::notationColorChanged() const
387 : {
388 0 : return m_notationColorChanged;
389 : }
390 :
391 0 : void NotationConfiguration::resetNotationColor()
392 : {
393 0 : engravingConfiguration()->resetDisplayedDefaultColors();
394 0 : }
395 :
396 0 : QColor NotationConfiguration::backgroundColor() const
397 : {
398 0 : if (uiConfiguration()->currentTheme().codeKey == LIGHT_THEME_CODE) {
399 0 : return settings()->value(LIGHT_SCORE_BACKGROUND_COLOR).toQColor();
400 0 : } else if (uiConfiguration()->currentTheme().codeKey == DARK_THEME_CODE) {
401 0 : return settings()->value(DARK_SCORE_BACKGROUND_COLOR).toQColor();
402 0 : } else if (uiConfiguration()->currentTheme().codeKey == HIGH_CONTRAST_BLACK_THEME_CODE) {
403 0 : return settings()->value(HC_BLACK_SCORE_BACKGROUND_COLOR).toQColor();
404 : } else {
405 0 : return settings()->value(HC_WHITE_SCORE_BACKGROUND_COLOR).toQColor();
406 : }
407 : }
408 :
409 0 : void NotationConfiguration::setBackgroundColor(const QColor& color)
410 : {
411 0 : if (uiConfiguration()->currentTheme().codeKey == LIGHT_THEME_CODE) {
412 0 : settings()->setSharedValue(LIGHT_SCORE_BACKGROUND_COLOR, Val(color));
413 0 : } else if (uiConfiguration()->currentTheme().codeKey == DARK_THEME_CODE) {
414 0 : settings()->setSharedValue(DARK_SCORE_BACKGROUND_COLOR, Val(color));
415 0 : } else if (uiConfiguration()->currentTheme().codeKey == HIGH_CONTRAST_BLACK_THEME_CODE) {
416 0 : settings()->setSharedValue(HC_BLACK_SCORE_BACKGROUND_COLOR, Val(color));
417 : } else {
418 0 : settings()->setSharedValue(HC_WHITE_SCORE_BACKGROUND_COLOR, Val(color));
419 : }
420 0 : }
421 :
422 0 : muse::io::path_t NotationConfiguration::backgroundWallpaperPath() const
423 : {
424 0 : return settings()->value(BACKGROUND_WALLPAPER_PATH).toString();
425 : }
426 :
427 0 : const QPixmap& NotationConfiguration::backgroundWallpaper() const
428 : {
429 0 : muse::io::path_t path = backgroundWallpaperPath();
430 :
431 0 : static QPixmap wallpaper;
432 0 : static muse::io::path_t lastPath;
433 :
434 0 : if (path.empty()) {
435 0 : wallpaper = QPixmap();
436 0 : } else if (path != lastPath) {
437 0 : wallpaper = QPixmap(path.toQString());
438 : }
439 :
440 0 : lastPath = path;
441 :
442 0 : return wallpaper;
443 0 : }
444 :
445 0 : void NotationConfiguration::setBackgroundWallpaperPath(const muse::io::path_t& path)
446 : {
447 0 : settings()->setSharedValue(BACKGROUND_WALLPAPER_PATH, Val(path.toStdString()));
448 0 : }
449 :
450 0 : bool NotationConfiguration::backgroundUseColor() const
451 : {
452 0 : return settings()->value(BACKGROUND_USE_COLOR).toBool();
453 : }
454 :
455 0 : void NotationConfiguration::setBackgroundUseColor(bool value)
456 : {
457 0 : settings()->setSharedValue(BACKGROUND_USE_COLOR, Val(value));
458 0 : }
459 :
460 0 : void NotationConfiguration::resetBackground()
461 : {
462 0 : settings()->setSharedValue(LIGHT_SCORE_BACKGROUND_COLOR, settings()->defaultValue(LIGHT_SCORE_BACKGROUND_COLOR));
463 0 : settings()->setSharedValue(DARK_SCORE_BACKGROUND_COLOR, settings()->defaultValue(DARK_SCORE_BACKGROUND_COLOR));
464 0 : settings()->setSharedValue(HC_BLACK_SCORE_BACKGROUND_COLOR, settings()->defaultValue(HC_BLACK_SCORE_BACKGROUND_COLOR));
465 0 : settings()->setSharedValue(HC_WHITE_SCORE_BACKGROUND_COLOR, settings()->defaultValue(HC_WHITE_SCORE_BACKGROUND_COLOR));
466 :
467 0 : settings()->setSharedValue(BACKGROUND_USE_COLOR, settings()->defaultValue(BACKGROUND_USE_COLOR));
468 :
469 0 : settings()->setSharedValue(BACKGROUND_WALLPAPER_PATH, settings()->defaultValue(BACKGROUND_WALLPAPER_PATH));
470 0 : }
471 :
472 0 : muse::async::Notification NotationConfiguration::backgroundChanged() const
473 : {
474 0 : return m_backgroundChanged;
475 : }
476 :
477 0 : QColor NotationConfiguration::foregroundColor() const
478 : {
479 0 : if (shouldInvertScore()) {
480 0 : return settings()->value(INVERTED_FOREGROUND_COLOR).toQColor();
481 : }
482 :
483 0 : return settings()->value(FOREGROUND_COLOR).toQColor();
484 : }
485 :
486 0 : void NotationConfiguration::setForegroundColor(const QColor& color)
487 : {
488 0 : if (shouldInvertScore()) {
489 0 : settings()->setSharedValue(INVERTED_FOREGROUND_COLOR, Val(color));
490 : } else {
491 0 : settings()->setSharedValue(FOREGROUND_COLOR, Val(color));
492 : }
493 0 : }
494 :
495 0 : muse::io::path_t NotationConfiguration::foregroundWallpaperPath() const
496 : {
497 0 : return settings()->value(FOREGROUND_WALLPAPER_PATH).toString();
498 : }
499 :
500 0 : const QPixmap& NotationConfiguration::foregroundWallpaper() const
501 : {
502 0 : muse::io::path_t path = foregroundWallpaperPath();
503 :
504 0 : static QPixmap wallpaper;
505 0 : static muse::io::path_t lastPath;
506 :
507 0 : if (path.empty()) {
508 0 : wallpaper = QPixmap();
509 0 : } else if (path != lastPath) {
510 0 : wallpaper = QPixmap(path.toQString());
511 : }
512 :
513 0 : lastPath = path;
514 :
515 0 : return wallpaper;
516 0 : }
517 :
518 0 : void NotationConfiguration::setForegroundWallpaperPath(const muse::io::path_t& path)
519 : {
520 0 : return settings()->setSharedValue(FOREGROUND_WALLPAPER_PATH, Val(path.toStdString()));
521 : }
522 :
523 0 : bool NotationConfiguration::foregroundUseColor() const
524 : {
525 0 : return settings()->value(FOREGROUND_USE_COLOR).toBool();
526 : }
527 :
528 0 : void NotationConfiguration::setForegroundUseColor(bool value)
529 : {
530 0 : settings()->setSharedValue(FOREGROUND_USE_COLOR, Val(value));
531 0 : }
532 :
533 0 : void NotationConfiguration::resetForeground()
534 : {
535 0 : settings()->setSharedValue(FOREGROUND_COLOR, settings()->defaultValue(FOREGROUND_COLOR));
536 0 : settings()->setSharedValue(INVERTED_FOREGROUND_COLOR, settings()->defaultValue(INVERTED_FOREGROUND_COLOR));
537 0 : settings()->setSharedValue(FOREGROUND_USE_COLOR, settings()->defaultValue(FOREGROUND_USE_COLOR));
538 0 : settings()->setSharedValue(FOREGROUND_WALLPAPER_PATH, settings()->defaultValue(FOREGROUND_WALLPAPER_PATH));
539 0 : settings()->setSharedValue(INVERT_SCORE_COLOR, settings()->defaultValue(INVERT_SCORE_COLOR));
540 0 : settings()->setSharedValue(ONLY_INVERT_IN_DARK_THEME, settings()->defaultValue(ONLY_INVERT_IN_DARK_THEME));
541 0 : }
542 :
543 0 : muse::async::Notification NotationConfiguration::foregroundChanged() const
544 : {
545 0 : return m_foregroundChanged;
546 : }
547 :
548 0 : muse::io::path_t NotationConfiguration::wallpapersDefaultDirPath() const
549 : {
550 0 : return globalConfiguration()->appDataPath() + "/wallpapers";
551 : }
552 :
553 0 : bool NotationConfiguration::shouldInvertScore() const
554 : {
555 0 : if (scoreInversionEnabled()) {
556 0 : return !isOnlyInvertInDarkTheme() || (uiConfiguration() && uiConfiguration()->isDarkMode());
557 : }
558 0 : return false;
559 : }
560 :
561 0 : bool NotationConfiguration::scoreInversionEnabled() const
562 : {
563 0 : return settings()->value(INVERT_SCORE_COLOR).toBool();
564 : }
565 :
566 0 : void NotationConfiguration::setScoreInversionEnabled(bool value)
567 : {
568 0 : settings()->setSharedValue(INVERT_SCORE_COLOR, Val(value));
569 0 : }
570 :
571 0 : muse::async::Notification NotationConfiguration::scoreInversionChanged() const
572 : {
573 0 : return m_scoreInversionChanged;
574 : }
575 :
576 0 : bool NotationConfiguration::isOnlyInvertInDarkTheme() const
577 : {
578 0 : return settings()->value(ONLY_INVERT_IN_DARK_THEME).toBool();
579 : }
580 :
581 0 : void NotationConfiguration::setOnlyInvertInDarkTheme(bool value)
582 : {
583 0 : settings()->setSharedValue(ONLY_INVERT_IN_DARK_THEME, Val(value));
584 0 : }
585 :
586 0 : muse::async::Notification NotationConfiguration::isOnlyInvertInDarkThemeChanged() const
587 : {
588 0 : return m_isOnlyInvertInDarkThemeChanged;
589 : }
590 :
591 0 : QColor NotationConfiguration::borderColor() const
592 : {
593 0 : if (uiConfiguration()->isHighContrast()) {
594 0 : return QColorConstants::White;
595 : } else {
596 0 : return QColor(0, 0, 0, 102);
597 : }
598 : }
599 :
600 0 : int NotationConfiguration::borderWidth() const
601 : {
602 0 : if (uiConfiguration()->isHighContrast()) {
603 0 : return 10;
604 : } else {
605 0 : return 1;
606 : }
607 : }
608 :
609 0 : QColor NotationConfiguration::playbackCursorColor() const
610 : {
611 0 : QColor color = selectionColor();
612 0 : color.setAlpha(178);
613 0 : return color;
614 : }
615 :
616 0 : int NotationConfiguration::cursorOpacity() const
617 : {
618 0 : return 50;
619 : }
620 :
621 0 : bool NotationConfiguration::thinNoteInputCursor() const
622 : {
623 0 : return settings()->value(THIN_NOTE_INPUT_CURSOR).toBool();
624 : }
625 :
626 0 : QColor NotationConfiguration::loopMarkerColor() const
627 : {
628 0 : return QColor(0x2456AA);
629 : }
630 :
631 0 : QColor NotationConfiguration::selectionColor(engraving::voice_idx_t voiceIndex) const
632 : {
633 0 : return engravingConfiguration()->selectionColor(voiceIndex).toQColor();
634 : }
635 :
636 0 : QColor NotationConfiguration::highlightSelectionColor(engraving::voice_idx_t voiceIndex) const
637 : {
638 0 : return engravingConfiguration()->highlightSelectionColor(voiceIndex).toQColor();
639 : }
640 :
641 0 : QColor NotationConfiguration::dropRectColor() const
642 : {
643 0 : QColor color = selectionColor();
644 0 : color.setAlpha(80);
645 0 : return color;
646 : }
647 :
648 0 : muse::draw::Color NotationConfiguration::noteInputPreviewColor() const
649 : {
650 0 : return settings()->value(NOTE_INPUT_PREVIEW_COLOR).toQColor();
651 : }
652 :
653 0 : bool NotationConfiguration::useNoteInputCursorInInputByDuration() const
654 : {
655 0 : return settings()->value(USE_NOTE_INPUT_CURSOR_IN_INPUT_BY_DURATION).toBool();
656 : }
657 :
658 0 : void NotationConfiguration::setUseNoteInputCursorInInputByDuration(bool use)
659 : {
660 0 : settings()->setSharedValue(USE_NOTE_INPUT_CURSOR_IN_INPUT_BY_DURATION, Val(use));
661 0 : }
662 :
663 0 : muse::async::Notification NotationConfiguration::useNoteInputCursorInInputByDurationChanged() const
664 : {
665 0 : return m_useNoteInputCursorInInputByDurationChanged;
666 : }
667 :
668 0 : int NotationConfiguration::selectionProximity() const
669 : {
670 0 : return settings()->value(SELECTION_PROXIMITY).toInt();
671 : }
672 :
673 0 : void NotationConfiguration::setSelectionProximity(int proximity)
674 : {
675 0 : settings()->setSharedValue(SELECTION_PROXIMITY, Val(proximity));
676 0 : }
677 :
678 0 : Channel<int> NotationConfiguration::selectionProximityChanged() const
679 : {
680 0 : return m_selectionProximityChanged;
681 : }
682 :
683 0 : ZoomType NotationConfiguration::defaultZoomType() const
684 : {
685 0 : return settings()->value(DEFAULT_ZOOM_TYPE).toEnum<ZoomType>();
686 : }
687 :
688 0 : void NotationConfiguration::setDefaultZoomType(ZoomType zoomType)
689 : {
690 0 : settings()->setSharedValue(DEFAULT_ZOOM_TYPE, Val(zoomType));
691 0 : }
692 :
693 0 : int NotationConfiguration::defaultZoom() const
694 : {
695 0 : return settings()->value(DEFAULT_ZOOM).toInt();
696 : }
697 :
698 0 : void NotationConfiguration::setDefaultZoom(int zoomPercentage)
699 : {
700 0 : settings()->setSharedValue(DEFAULT_ZOOM, Val(zoomPercentage));
701 0 : }
702 :
703 0 : Notification NotationConfiguration::defaultZoomChanged() const
704 : {
705 0 : return m_defaultZoomChanged;
706 : }
707 :
708 0 : QList<int> NotationConfiguration::possibleZoomPercentageList() const
709 : {
710 : return {
711 : 5, 10, 15, 25, 50, 75, 100, 150, 200, 400, 800, 1600
712 0 : };
713 : }
714 :
715 0 : engraving::AutomationType NotationConfiguration::currentAutomationType() const
716 : {
717 0 : return settings()->value(CURRENT_AUTOMATION_TYPE).toEnum<engraving::AutomationType>();
718 : }
719 :
720 0 : void NotationConfiguration::setCurrentAutomationType(engraving::AutomationType type)
721 : {
722 0 : settings()->setSharedValue(CURRENT_AUTOMATION_TYPE, Val(type));
723 0 : }
724 :
725 0 : Notification NotationConfiguration::currentAutomationTypeChanged() const
726 : {
727 0 : return m_currentAutomationTypeChanged;
728 : }
729 :
730 0 : int NotationConfiguration::mouseZoomPrecision() const
731 : {
732 0 : return settings()->value(MOUSE_ZOOM_PRECISION).toInt();
733 : }
734 :
735 0 : void NotationConfiguration::setMouseZoomPrecision(int precision)
736 : {
737 0 : settings()->setSharedValue(MOUSE_ZOOM_PRECISION, Val(precision));
738 0 : }
739 :
740 0 : Notification NotationConfiguration::mouseZoomPrecisionChanged() const
741 : {
742 0 : return m_mouseZoomPrecisionChanged;
743 : }
744 :
745 0 : std::string NotationConfiguration::fontFamily() const
746 : {
747 0 : return uiConfiguration()->fontFamily();
748 : }
749 :
750 0 : int NotationConfiguration::fontSize() const
751 : {
752 0 : return uiConfiguration()->fontSize(FontSizeType::BODY);
753 : }
754 :
755 0 : muse::io::path_t NotationConfiguration::userStylesPath() const
756 : {
757 0 : return settings()->value(USER_STYLES_PATH).toPath();
758 : }
759 :
760 0 : void NotationConfiguration::setUserStylesPath(const muse::io::path_t& path)
761 : {
762 0 : settings()->setSharedValue(USER_STYLES_PATH, Val(path));
763 0 : }
764 :
765 0 : muse::async::Channel<muse::io::path_t> NotationConfiguration::userStylesPathChanged() const
766 : {
767 0 : return m_userStylesPathChanged;
768 : }
769 :
770 0 : muse::io::path_t NotationConfiguration::defaultStyleFilePath() const
771 : {
772 0 : return engravingConfiguration()->defaultStyleFilePath();
773 : }
774 :
775 0 : void NotationConfiguration::setDefaultStyleFilePath(const muse::io::path_t& path)
776 : {
777 0 : engravingConfiguration()->setDefaultStyleFilePath(path.toQString());
778 0 : }
779 :
780 0 : async::Channel<muse::io::path_t> NotationConfiguration::defaultStyleFilePathChanged() const
781 : {
782 0 : return engravingConfiguration()->defaultStyleFilePathChanged();
783 : }
784 :
785 0 : muse::io::path_t NotationConfiguration::partStyleFilePath() const
786 : {
787 0 : return engravingConfiguration()->partStyleFilePath();
788 : }
789 :
790 0 : void NotationConfiguration::setPartStyleFilePath(const muse::io::path_t& path)
791 : {
792 0 : engravingConfiguration()->setPartStyleFilePath(path.toQString());
793 0 : }
794 :
795 0 : async::Channel<muse::io::path_t> NotationConfiguration::partStyleFilePathChanged() const
796 : {
797 0 : return engravingConfiguration()->partStyleFilePathChanged();
798 : }
799 :
800 0 : muse::io::path_t NotationConfiguration::userMusicFontsPath() const
801 : {
802 0 : return settings()->value(USER_MUSIC_FONTS_PATH).toPath();
803 : }
804 :
805 0 : void NotationConfiguration::setUserMusicFontsPath(const muse::io::path_t& path)
806 : {
807 0 : settings()->setSharedValue(USER_MUSIC_FONTS_PATH, Val(path));
808 0 : }
809 :
810 0 : muse::async::Channel<muse::io::path_t> NotationConfiguration::userMusicFontsPathChanged() const
811 : {
812 0 : return m_userMusicFontsPathChanged;
813 : }
814 :
815 0 : NoteInputMethod NotationConfiguration::defaultNoteInputMethod() const
816 : {
817 0 : std::string str = settings()->value(DEFAULT_NOTE_INPUT_METHOD).toString();
818 0 : return muse::key(NOTE_INPUT_METHOD_TO_STR, str, NoteInputMethod::BY_NOTE_NAME);
819 0 : }
820 :
821 0 : void NotationConfiguration::setDefaultNoteInputMethod(NoteInputMethod method)
822 : {
823 0 : std::string str = muse::value(NOTE_INPUT_METHOD_TO_STR, method);
824 0 : settings()->setSharedValue(DEFAULT_NOTE_INPUT_METHOD, Val(str));
825 0 : }
826 :
827 0 : async::Notification NotationConfiguration::defaultNoteInputMethodChanged() const
828 : {
829 0 : return m_defaultNoteInputMethodChanged;
830 : }
831 :
832 0 : bool NotationConfiguration::addAccidentalDotsArticulationsToNextNoteEntered() const
833 : {
834 0 : return settings()->value(ADD_ACCIDENTAL_ARTICULATIONS_DOTS_TO_NEXT_NOTE_ENTERED).toBool();
835 : }
836 :
837 0 : void NotationConfiguration::setAddAccidentalDotsArticulationsToNextNoteEntered(bool value)
838 : {
839 0 : settings()->setSharedValue(ADD_ACCIDENTAL_ARTICULATIONS_DOTS_TO_NEXT_NOTE_ENTERED, Val(value));
840 0 : }
841 :
842 0 : muse::async::Notification NotationConfiguration::addAccidentalDotsArticulationsToNextNoteEnteredChanged() const
843 : {
844 0 : return m_addAccidentalDotsArticulationsToNextNoteEnteredChanged;
845 : }
846 :
847 0 : bool NotationConfiguration::isMidiInputEnabled() const
848 : {
849 0 : return settings()->value(IS_MIDI_INPUT_ENABLED).toBool();
850 : }
851 :
852 0 : void NotationConfiguration::setIsMidiInputEnabled(bool enabled)
853 : {
854 0 : settings()->setSharedValue(IS_MIDI_INPUT_ENABLED, Val(enabled));
855 0 : }
856 :
857 0 : async::Notification NotationConfiguration::isMidiInputEnabledChanged() const
858 : {
859 0 : return m_isMidiInputEnabledChanged;
860 : }
861 :
862 0 : bool NotationConfiguration::startNoteInputAtSelectedNoteRestWhenPressingMidiKey() const
863 : {
864 0 : return settings()->value(START_NOTE_INPUT_AT_SELECTED_NOTE_REST_WHEN_PRESSING_MIDI_KEY).toBool();
865 : }
866 :
867 0 : void NotationConfiguration::setStartNoteInputAtSelectedNoteRestWhenPressingMidiKey(bool value)
868 : {
869 0 : settings()->setSharedValue(START_NOTE_INPUT_AT_SELECTED_NOTE_REST_WHEN_PRESSING_MIDI_KEY, Val(value));
870 0 : }
871 :
872 0 : async::Notification NotationConfiguration::startNoteInputAtSelectedNoteRestWhenPressingMidiKeyChanged() const
873 : {
874 0 : return m_startNoteInputAtSelectedNoteRestWhenPressingMidiKeyChanged;
875 : }
876 :
877 0 : bool NotationConfiguration::isAutomaticallyPanEnabled() const
878 : {
879 0 : return settings()->value(IS_AUTOMATICALLY_PAN_ENABLED).toBool();
880 : }
881 :
882 0 : void NotationConfiguration::setIsAutomaticallyPanEnabled(bool enabled)
883 : {
884 0 : settings()->setSharedValue(IS_AUTOMATICALLY_PAN_ENABLED, Val(enabled));
885 0 : }
886 :
887 0 : Notification NotationConfiguration::isAutomaticallyPanEnabledChanged() const
888 : {
889 0 : return m_isAutomaticallyPanEnabledChanged;
890 : }
891 :
892 0 : bool NotationConfiguration::isPlayRepeatsEnabled() const
893 : {
894 0 : return settings()->value(IS_PLAY_REPEATS_ENABLED).toBool();
895 : }
896 :
897 0 : void NotationConfiguration::setIsPlayRepeatsEnabled(bool enabled)
898 : {
899 0 : settings()->setSharedValue(IS_PLAY_REPEATS_ENABLED, Val(enabled));
900 0 : m_isPlayRepeatsChanged.notify();
901 0 : }
902 :
903 0 : Notification NotationConfiguration::isPlayRepeatsChanged() const
904 : {
905 0 : return m_isPlayRepeatsChanged;
906 : }
907 :
908 0 : bool NotationConfiguration::isPlayChordSymbolsEnabled() const
909 : {
910 0 : return settings()->value(IS_PLAY_CHORD_SYMBOLS_ENABLED).toBool();
911 : }
912 :
913 0 : void NotationConfiguration::setIsPlayChordSymbolsEnabled(bool enabled)
914 : {
915 0 : settings()->setSharedValue(IS_PLAY_CHORD_SYMBOLS_ENABLED, Val(enabled));
916 0 : }
917 :
918 0 : muse::async::Notification NotationConfiguration::isPlayChordSymbolsChanged() const
919 : {
920 0 : return m_isPlayChordSymbolsChanged;
921 : }
922 :
923 0 : bool NotationConfiguration::isPlayPreviewNotesInInputByDuration() const
924 : {
925 0 : return settings()->value(IS_PLAY_PREVIEW_NOTES_IN_INPUT_BY_DURATION_ENABLED).toBool();
926 : }
927 :
928 0 : void NotationConfiguration::setIsPlayPreviewNotesInInputByDuration(bool play)
929 : {
930 0 : settings()->setSharedValue(IS_PLAY_PREVIEW_NOTES_IN_INPUT_BY_DURATION_ENABLED, Val(play));
931 0 : }
932 :
933 0 : muse::async::Notification NotationConfiguration::isPlayPreviewNotesInInputByDurationChanged() const
934 : {
935 0 : return m_isPlayNotesPreviewInInputByDurationChanged;
936 : }
937 :
938 0 : bool NotationConfiguration::playPreviewNotesWithScoreDynamics() const
939 : {
940 0 : return settings()->value(PLAY_PREVIEW_NOTES_WITH_SCORE_DYNAMICS).toBool();
941 : }
942 :
943 0 : void NotationConfiguration::setPlayPreviewNotesWithScoreDynamics(bool use)
944 : {
945 0 : settings()->setSharedValue(PLAY_PREVIEW_NOTES_WITH_SCORE_DYNAMICS, Val(use));
946 0 : }
947 :
948 0 : muse::async::Notification NotationConfiguration::playPreviewNotesWithScoreDynamicsChanged() const
949 : {
950 0 : return m_playPreviewNotesWithScoreDynamicsChanged;
951 : }
952 :
953 0 : bool NotationConfiguration::isMetronomeEnabled() const
954 : {
955 0 : return settings()->value(IS_METRONOME_ENABLED).toBool();
956 : }
957 :
958 0 : void NotationConfiguration::setIsMetronomeEnabled(bool enabled)
959 : {
960 0 : settings()->setSharedValue(IS_METRONOME_ENABLED, Val(enabled));
961 0 : }
962 :
963 0 : muse::async::Notification NotationConfiguration::isMetronomeEnabledChanged() const
964 : {
965 0 : return m_isMetronomeEnabledChanged;
966 : }
967 :
968 0 : bool NotationConfiguration::isCountInEnabled() const
969 : {
970 0 : return settings()->value(IS_COUNT_IN_ENABLED).toBool();
971 : }
972 :
973 0 : void NotationConfiguration::setIsCountInEnabled(bool enabled)
974 : {
975 0 : settings()->setSharedValue(IS_COUNT_IN_ENABLED, Val(enabled));
976 0 : }
977 :
978 0 : Notification NotationConfiguration::isCountInEnabledChanged() const
979 : {
980 0 : return m_isCountInEnabledChanged;
981 : }
982 :
983 0 : ValCh<muse::Orientation> NotationConfiguration::canvasOrientation() const
984 : {
985 0 : ValCh<muse::Orientation> orientation;
986 0 : orientation.ch = m_canvasOrientationChanged;
987 0 : bool isVertical = settings()->value(IS_CANVAS_ORIENTATION_VERTICAL_KEY).toBool();
988 0 : orientation.val = isVertical ? muse::Orientation::Vertical : muse::Orientation::Horizontal;
989 :
990 0 : return orientation;
991 0 : }
992 :
993 0 : void NotationConfiguration::setCanvasOrientation(muse::Orientation orientation)
994 : {
995 0 : bool isVertical = orientation == muse::Orientation::Vertical;
996 0 : mu::engraving::MScore::setVerticalOrientation(isVertical);
997 :
998 0 : settings()->setSharedValue(IS_CANVAS_ORIENTATION_VERTICAL_KEY, Val(isVertical));
999 0 : }
1000 :
1001 0 : bool NotationConfiguration::colorNotesOutsideOfUsablePitchRange() const
1002 : {
1003 0 : return settings()->value(COLOR_NOTES_OUTSIDE_OF_USABLE_PITCH_RANGE).toBool();
1004 : }
1005 :
1006 0 : void NotationConfiguration::setColorNotesOutsideOfUsablePitchRange(bool value)
1007 : {
1008 0 : mu::engraving::MScore::warnPitchRange = value;
1009 0 : settings()->setSharedValue(COLOR_NOTES_OUTSIDE_OF_USABLE_PITCH_RANGE, Val(value));
1010 0 : }
1011 :
1012 0 : async::Channel<bool> NotationConfiguration::colorNotesOutsideOfUsablePitchRangeChanged() const
1013 : {
1014 0 : return m_colorNotesOutsideOfUsablePitchRangeChanged;
1015 : }
1016 :
1017 0 : bool NotationConfiguration::warnGuitarBends() const
1018 : {
1019 0 : return settings()->value(WARN_GUITAR_BENDS).toBool();
1020 : }
1021 :
1022 0 : void NotationConfiguration::setWarnGuitarBends(bool value)
1023 : {
1024 0 : mu::engraving::MScore::warnGuitarBends = value;
1025 0 : settings()->setSharedValue(WARN_GUITAR_BENDS, Val(value));
1026 0 : }
1027 :
1028 0 : async::Channel<bool> NotationConfiguration::warnGuitarBendsChanged() const
1029 : {
1030 0 : return m_warnGuitarBendsChanged;
1031 : }
1032 :
1033 0 : int NotationConfiguration::delayBetweenNotesInRealTimeModeMilliseconds() const
1034 : {
1035 0 : return settings()->value(REALTIME_DELAY).toInt();
1036 : }
1037 :
1038 0 : void NotationConfiguration::setDelayBetweenNotesInRealTimeModeMilliseconds(int delayMs)
1039 : {
1040 0 : settings()->setSharedValue(REALTIME_DELAY, Val(delayMs));
1041 0 : }
1042 :
1043 0 : async::Channel<int> NotationConfiguration::delayBetweenNotesInRealTimeModeMillisecondsChanged() const
1044 : {
1045 0 : return m_delayBetweenNotesInRealTimeModeMillisecondsChanged;
1046 : }
1047 :
1048 0 : bool NotationConfiguration::useMidiVelocityAndDurationDuringNoteInput() const
1049 : {
1050 0 : return settings()->value(USE_MIDI_VELOCITY_AND_DURATION_DURING_NOTE_INPUT).toBool();
1051 : }
1052 :
1053 0 : void NotationConfiguration::setUseMidiVelocityAndDurationDuringNoteInput(bool use)
1054 : {
1055 0 : settings()->setSharedValue(USE_MIDI_VELOCITY_AND_DURATION_DURING_NOTE_INPUT, Val(use));
1056 0 : }
1057 :
1058 0 : muse::async::Channel<bool> NotationConfiguration::useMidiVelocityAndDurationDuringNoteInputChanged() const
1059 : {
1060 0 : return m_useMidiVelocityAndDurationDuringNoteInputChanged;
1061 : }
1062 :
1063 0 : int NotationConfiguration::notePlayDurationMilliseconds() const
1064 : {
1065 0 : return settings()->value(NOTE_DEFAULT_PLAY_DURATION).toInt();
1066 : }
1067 :
1068 0 : void NotationConfiguration::setNotePlayDurationMilliseconds(int durationMs)
1069 : {
1070 0 : settings()->setSharedValue(NOTE_DEFAULT_PLAY_DURATION, Val(durationMs));
1071 0 : }
1072 :
1073 0 : async::Channel<int> NotationConfiguration::notePlayDurationMillisecondsChanged() const
1074 : {
1075 0 : return m_notePlayDurationMillisecondsChanged;
1076 : }
1077 :
1078 0 : void NotationConfiguration::setTemplateModeEnabled(std::optional<bool> enabled)
1079 : {
1080 0 : mu::engraving::MScore::saveTemplateMode = enabled ? enabled.value() : false;
1081 0 : }
1082 :
1083 0 : void NotationConfiguration::setTestModeEnabled(std::optional<bool> enabled)
1084 : {
1085 0 : mu::engraving::MScore::testMode = enabled ? enabled.value() : false;
1086 0 : }
1087 :
1088 0 : muse::io::path_t NotationConfiguration::instrumentsXmlPath() const
1089 : {
1090 0 : return ":/engraving/instruments/instruments.xml";
1091 : }
1092 :
1093 0 : muse::io::path_t NotationConfiguration::scoreOrdersXmlPath() const
1094 : {
1095 0 : return ":/engraving/instruments/orders.xml";
1096 : }
1097 :
1098 0 : muse::io::path_t NotationConfiguration::userInstrumentsFolder() const
1099 : {
1100 0 : return settings()->value(USER_INSTRUMENTS_PATH).toPath();
1101 : }
1102 :
1103 0 : muse::io::paths_t NotationConfiguration::userInstrumentsAndScoreOrdersPaths() const
1104 : {
1105 0 : muse::io::paths_t paths;
1106 :
1107 : // Scan user instruments folder for XML files
1108 0 : muse::io::path_t folder = userInstrumentsFolder();
1109 0 : if (!folder.empty()) {
1110 0 : RetVal<io::paths_t> userFiles = fileSystem()->scanFiles(folder, { "*.xml" }, io::ScanMode::FilesInCurrentDir);
1111 0 : if (userFiles.ret) {
1112 0 : for (const io::path_t& file : userFiles.val) {
1113 0 : paths.push_back(file);
1114 : }
1115 : }
1116 0 : }
1117 :
1118 0 : return paths;
1119 0 : }
1120 :
1121 0 : void NotationConfiguration::setUserInstrumentsFolder(const muse::io::path_t& path)
1122 : {
1123 0 : settings()->setSharedValue(USER_INSTRUMENTS_PATH, Val(path));
1124 0 : }
1125 :
1126 0 : muse::async::Channel<muse::io::path_t> NotationConfiguration::userInstrumentsFolderChanged() const
1127 : {
1128 0 : return m_userInstrumentsFolderChanged;
1129 : }
1130 :
1131 0 : muse::io::path_t NotationConfiguration::stringTuningsPresetsPath() const
1132 : {
1133 0 : return ":/engraving/instruments/string_tunings_presets.json";
1134 : }
1135 :
1136 0 : bool NotationConfiguration::isSnappedToGrid(muse::Orientation gridOrientation) const
1137 : {
1138 0 : switch (gridOrientation) {
1139 0 : case muse::Orientation::Horizontal: return settings()->value(IS_SNAPPED_TO_HORIZONTAL_GRID_KEY).toBool();
1140 0 : case muse::Orientation::Vertical: return settings()->value(IS_SNAPPED_TO_VERTICAL_GRID_KEY).toBool();
1141 : }
1142 :
1143 0 : return false;
1144 : }
1145 :
1146 0 : void NotationConfiguration::setIsSnappedToGrid(muse::Orientation gridOrientation, bool isSnapped)
1147 : {
1148 0 : switch (gridOrientation) {
1149 0 : case muse::Orientation::Horizontal:
1150 0 : settings()->setSharedValue(IS_SNAPPED_TO_HORIZONTAL_GRID_KEY, Val(isSnapped));
1151 0 : break;
1152 0 : case muse::Orientation::Vertical:
1153 0 : settings()->setSharedValue(IS_SNAPPED_TO_VERTICAL_GRID_KEY, Val(isSnapped));
1154 0 : break;
1155 : }
1156 0 : }
1157 :
1158 0 : int NotationConfiguration::gridSizeSpatium(muse::Orientation gridOrientation) const
1159 : {
1160 0 : switch (gridOrientation) {
1161 0 : case muse::Orientation::Horizontal: return settings()->value(HORIZONTAL_GRID_SIZE_KEY).toInt();
1162 0 : case muse::Orientation::Vertical: return settings()->value(VERTICAL_GRID_SIZE_KEY).toInt();
1163 : }
1164 :
1165 0 : return DEFAULT_GRID_SIZE_SPATIUM;
1166 : }
1167 :
1168 0 : void NotationConfiguration::setGridSize(muse::Orientation gridOrientation, int sizeSpatium)
1169 : {
1170 0 : switch (gridOrientation) {
1171 0 : case muse::Orientation::Horizontal:
1172 0 : mu::engraving::MScore::setHRaster(sizeSpatium);
1173 0 : settings()->setSharedValue(HORIZONTAL_GRID_SIZE_KEY, Val(sizeSpatium));
1174 0 : break;
1175 0 : case muse::Orientation::Vertical:
1176 0 : mu::engraving::MScore::setVRaster(sizeSpatium);
1177 0 : settings()->setSharedValue(VERTICAL_GRID_SIZE_KEY, Val(sizeSpatium));
1178 0 : break;
1179 : }
1180 0 : }
1181 :
1182 0 : bool NotationConfiguration::needToShowMScoreError(const std::string& errorKey) const
1183 : {
1184 0 : Settings::Key key(module_name, "ui/dialogs/needToShowMScoreError/" + errorKey);
1185 :
1186 0 : settings()->setDefaultValue(key, Val(true));
1187 :
1188 0 : return settings()->value(key).toBool();
1189 0 : }
1190 :
1191 0 : void NotationConfiguration::setNeedToShowMScoreError(const std::string& errorKey, bool show)
1192 : {
1193 0 : Settings::Key key(module_name, "ui/dialogs/needToShowMScoreError/" + errorKey);
1194 0 : settings()->setSharedValue(key, Val(show));
1195 0 : }
1196 :
1197 0 : ValCh<bool> NotationConfiguration::midiUseWrittenPitch() const
1198 : {
1199 0 : return m_midiInputUseWrittenPitch;
1200 : }
1201 :
1202 0 : void NotationConfiguration::setMidiUseWrittenPitch(bool useWrittenPitch)
1203 : {
1204 0 : settings()->setSharedValue(USE_MIDI_INPUT_WRITTEN_PITCH, Val(useWrittenPitch));
1205 0 : }
1206 :
1207 0 : muse::io::path_t NotationConfiguration::styleFileImportPath() const
1208 : {
1209 0 : return settings()->value(STYLE_FILE_IMPORT_PATH_KEY).toString();
1210 : }
1211 :
1212 0 : void NotationConfiguration::setStyleFileImportPath(const muse::io::path_t& path)
1213 : {
1214 0 : settings()->setSharedValue(STYLE_FILE_IMPORT_PATH_KEY, Val(path.toStdString()));
1215 0 : }
1216 :
1217 0 : async::Channel<std::string> NotationConfiguration::styleFileImportPathChanged() const
1218 : {
1219 0 : return m_styleFileImportPathChanged;
1220 : }
|