LCOV - code coverage report
Current view: top level - src/notation/internal - notationconfiguration.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 619 0
Test Date: 2026-11-05 04:07:02

            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              : }
        

Generated by: LCOV version 2.0-1