LCOV - code coverage report
Current view: top level - src/appshell/qml/MuseScore/AppShell - appmenumodel.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 510 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 "appmenumodel.h"
      23              : 
      24              : #include "log.h"
      25              : #include "rcommand/commandtypes.h"
      26              : #include "types/translatablestring.h"
      27              : 
      28              : #include "muse_framework_config.h"
      29              : 
      30              : #ifdef MUSE_MODULE_WORKSPACE
      31              : #include "workspace/qml/Muse/Workspace/workspacesmenumodel.h"
      32              : #endif
      33              : 
      34              : #include "notation/inotation.h"
      35              : #include "notation/inotationundostack.h"
      36              : #include "notationscene/notationcommands.h"
      37              : 
      38              : #include "appshell/appshellcommands.h"
      39              : #include "project/projectcommands.h"
      40              : #include "notationscene/notationcommands.h"
      41              : #include "playback/playbackcommands.h"
      42              : #include "palette/palettecommands.h"
      43              : #include "dockwindow_v2/dockcommands.h"
      44              : #include "update/updatecommands.h"
      45              : #include "diagnostics/diagnosticscommands.h"
      46              : #include "musesampler/musesamplercommands.h"
      47              : #include "vst/vstcommands.h"
      48              : #include "audio/main/audiocommands.h"
      49              : #include "multiwindows/multiwindowscommands.h"
      50              : #include "extensions/extensionscommands.h"
      51              : #include "testflow/testflowcommands.h"
      52              : 
      53              : using namespace muse;
      54              : using namespace mu::appshell;
      55              : using namespace muse::ui;
      56              : using namespace muse::uicomponents;
      57              : using namespace mu::project;
      58              : using namespace muse::workspace;
      59              : using namespace muse::extensions;
      60              : using namespace mu::notation;
      61              : using namespace mu::playback;
      62              : using namespace mu::palette;
      63              : using namespace muse::dock;
      64              : using namespace muse::update;
      65              : using namespace muse::diagnostics;
      66              : using namespace muse::musesampler;
      67              : using namespace muse::vst;
      68              : using namespace muse::audio;
      69              : using namespace muse::mi;
      70              : using namespace muse::testflow;
      71              : 
      72            0 : AppMenuModel::AppMenuModel(QObject* parent)
      73            0 :     : AbstractMenuModel(parent)
      74              : {
      75            0 :     setObjectName("AppMenuModel");
      76              : 
      77              : #ifdef MUSE_MODULE_WORKSPACE
      78            0 :     m_workspacesMenuModel = std::make_shared<WorkspacesMenuModel>(this);
      79              : #endif
      80            0 : }
      81              : 
      82            0 : void AppMenuModel::load()
      83              : {
      84            0 :     TRACEFUNC;
      85              : 
      86            0 :     AbstractMenuModel::load();
      87              : 
      88              : #ifdef MUSE_MODULE_WORKSPACE
      89            0 :     m_workspacesMenuModel->load();
      90              : #endif
      91              : 
      92              :     MenuItemList items {
      93            0 :         makeFileMenu(),
      94            0 :         makeEditMenu(),
      95            0 :         makeViewMenu(),
      96            0 :         makeAddMenu(),
      97            0 :         makeFormatMenu(),
      98            0 :         makeToolsMenu(),
      99            0 :         makeExtensionsMenu()
     100            0 :     };
     101              : 
     102            0 :     if (globalConfiguration()->devModeEnabled()) {
     103            0 :         items << makeHelpMenu(false);
     104            0 :         items << makeDiagnosticsMenu();
     105              :     } else {
     106            0 :         items << makeHelpMenu(true);
     107              :     }
     108              : 
     109            0 :     setItems(items);
     110              : 
     111            0 :     setupConnections();
     112              : 
     113              :     //! NOTE: removes some undesired platform-specific items
     114              :     //! (such as "Start Dictation" and "Special Characters" on macOS)
     115            0 :     appMenuModelHook()->onAppMenuInited();
     116            0 : }
     117              : 
     118            0 : bool AppMenuModel::isGlobalMenuAvailable()
     119              : {
     120            0 :     return uiConfiguration()->isGlobalMenuAvailable();
     121              : }
     122              : 
     123            0 : void AppMenuModel::setupConnections()
     124              : {
     125            0 :     recentFilesController()->recentFilesListChanged().onReceive(this, [this](const RecentFilesChange&) {
     126            0 :         MenuItem& recentMenuItem = findMenu("menu-file-open");
     127            0 :         MenuItemList recentSubMenuItems = makeRecentSubMenuItems();
     128            0 :         recentMenuItem.setSubitems(recentSubMenuItems);
     129            0 :         recentMenuItem.setEnabled(!recentSubMenuItems.empty());
     130            0 :     });
     131              : 
     132              : #ifdef MUSE_MODULE_WORKSPACE
     133            0 :     connect(m_workspacesMenuModel.get(), &WorkspacesMenuModel::itemsChanged, this, [this]() {
     134            0 :         MenuItem& workspacesItem = findMenu("menu-workspaces");
     135            0 :         workspacesItem.setSubitems(m_workspacesMenuModel->items());
     136            0 :     });
     137              : #endif
     138              : 
     139            0 :     extensionsRegister()->manifestListChanged().onNotify(this, [this]() {
     140            0 :         MenuItem& pluginsMenu = findMenu("menu-extensions");
     141            0 :         pluginsMenu.setSubitems(makeExtensionsSubitems());
     142            0 :     });
     143              : 
     144            0 :     extensionsRegister()->enabledChanged().onReceive(this, [this](const ExtensionUri&) {
     145            0 :         MenuItem& pluginsItem = findMenu("menu-extensions");
     146            0 :         pluginsItem.setSubitems(makeExtensionsSubitems());
     147            0 :     });
     148              : 
     149            0 :     projectSession()->currentNotationChanged().onNotify(this, [this]() {
     150            0 :         auto stack = undoStack();
     151            0 :         if (stack) {
     152            0 :             stack->stackChanged().onNotify(this, [this]() {
     153            0 :                 updateUndoRedoItems();
     154            0 :             }, Asyncable::Mode::SetReplace /* FIXME */);
     155              :         }
     156              : 
     157            0 :         updateUndoRedoItems();
     158            0 :     });
     159            0 : }
     160              : 
     161            0 : bool AppMenuModel::isMuseSamplerModuleAdded() const
     162              : {
     163              : #ifdef MUSE_MODULE_MUSESAMPLER
     164            0 :     return museSamplerInfo() != nullptr;
     165              : #else
     166              :     return false;
     167              : #endif
     168              : }
     169              : 
     170            0 : MenuItemList AppMenuModel::makeChordAndFretboardDiagramsItems()
     171              : {
     172              :     MenuItemList items {
     173            0 :         makeMenuItem(ADD_CHORD_TEXT_COMMAND),
     174            0 :         makeMenuItem(ADD_FRETBOARD_DIAGRAM_COMMAND),
     175            0 :         makeSeparator(),
     176            0 :         makeMenuItem(INSERT_FRETFRAME_COMMAND, TranslatableString("appshell/menu/add/chordandfret", "Fretboard diagram legend"))
     177            0 :     };
     178              : 
     179            0 :     return items;
     180              : }
     181              : 
     182            0 : MenuItem* AppMenuModel::makeMenuItem(const muse::rcommand::Command& command, MenuItemRole role)
     183              : {
     184            0 :     MenuItem* item = makeMenuItem(command);
     185            0 :     item->setRole(role);
     186            0 :     return item;
     187              : }
     188              : 
     189            0 : MenuItem* AppMenuModel::makeFileMenu()
     190              : {
     191            0 :     MenuItemList recentSubMenuItems = makeRecentSubMenuItems();
     192            0 :     bool openRecentEnabled = !recentSubMenuItems.isEmpty();
     193              : 
     194              :     MenuItemList fileItems {
     195            0 :         makeMenuItem(PROJECT_NEW_COMMAND),
     196            0 :         makeMenuItem(PROJECT_OPEN_COMMAND),
     197            0 :         makeMenu(TranslatableString("appshell/menu/file", "Open &recent"), recentSubMenuItems, "menu-file-open", openRecentEnabled),
     198            0 :         makeMenuItem(PROJECT_CLOSE_COMMAND),
     199            0 :         makeSeparator(),
     200            0 :         makeMenuItem(PROJECT_SAVE_COMMAND),
     201            0 :         makeMenuItem(PROJECT_SAVE_AS_COMMAND),
     202            0 :         makeMenuItem(PROJECT_SAVE_TO_CLOUD_COMMAND),
     203            0 :         makeMenu(TranslatableString("appshell/menu/file", "Save o&ther"), {
     204            0 :             makeMenuItem(PROJECT_SAVE_A_COPY_COMMAND),
     205            0 :             makeMenuItem(PROJECT_SAVE_SELECTION_COMMAND),
     206              :         }),
     207            0 :         makeMenu(TranslatableString("appshell/menu/file", "Pu&blish online"), {
     208            0 :             makeMenuItem(PROJECT_PUBLISH_COMMAND),
     209            0 :             makeMenuItem(PROJECT_SHARE_AUDIO_COMMAND),
     210              :         }),
     211            0 :         makeSeparator(),
     212            0 :         makeMenuItem(PROJECT_CONVERT_TO_SCORE_COMMAND),
     213            0 :         makeMenuItem(PROJECT_EXPORT_COMMAND),
     214            0 :         makeSeparator(),
     215            0 :         makeMenuItem(PROJECT_PROPERTIES_COMMAND),
     216            0 :         makeMenuItem(OPEN_PARTS_COMMAND),
     217            0 :         makeSeparator(),
     218            0 :         makeMenuItem(PROJECT_PRINT_COMMAND),
     219            0 :         makeSeparator(),
     220            0 :         makeMenuItem(APP_QUIT_COMMAND, MenuItemRole::QuitRole)
     221            0 :     };
     222              : 
     223            0 :     return makeMenu(TranslatableString("appshell/menu/file", "&File"), fileItems, "menu-file");
     224            0 : }
     225              : 
     226            0 : MenuItem* AppMenuModel::makeEditMenu()
     227              : {
     228              :     MenuItemList editItems {
     229            0 :         makeMenuItem(UNDO_COMMAND),
     230            0 :         makeMenuItem(REDO_COMMAND),
     231            0 :         makeMenuItem(DOCK_TOGGLE_UNDO_HISTORY_COMMAND),
     232            0 :         makeSeparator(),
     233            0 :         makeMenuItem(CUT_COMMAND),
     234            0 :         makeMenuItem(COPY_COMMAND),
     235            0 :         makeMenuItem(PASTE_COMMAND),
     236            0 :         makeMenuItem(PASTE_HALF_COMMAND),
     237            0 :         makeMenuItem(PASTE_DOUBLE_COMMAND),
     238            0 :         makeMenuItem(COPY_PASTE_SWAP_COMMAND),
     239            0 :         makeMenuItem(DELETE_COMMAND),
     240            0 :         makeSeparator(),
     241            0 :         makeMenuItem(SELECT_ALL_COMMAND),
     242            0 :         makeMenuItem(SELECT_SECTION_COMMAND),
     243            0 :         makeMenuItem(SHOW_SEARCH_COMMAND),
     244            0 :         makeSeparator(),
     245            0 :         makeMenuItem(APP_PREFERENCES_COMMAND, MenuItemRole::PreferencesRole)
     246            0 :     };
     247              : 
     248            0 :     return makeMenu(TranslatableString("appshell/menu/edit", "&Edit"), editItems, "menu-edit");
     249            0 : }
     250              : 
     251            0 : mu::notation::INotationUndoStackPtr AppMenuModel::undoStack() const
     252              : {
     253            0 :     mu::notation::INotationPtr notation = projectSession()->currentNotation();
     254            0 :     return notation ? notation->undoStack() : nullptr;
     255            0 : }
     256              : 
     257            0 : void AppMenuModel::updateUndoRedoItems()
     258              : {
     259            0 :     auto stack = undoStack();
     260              : 
     261            0 :     MenuItem& undoItem = findItem(UNDO_COMMAND);
     262            0 :     const TranslatableString undoActionName = stack ? stack->topMostUndoActionName() : TranslatableString();
     263            0 :     undoItem.setTitle(undoActionName.isEmpty()
     264            0 :                       ? TranslatableString("action", "Undo")
     265            0 :                       : TranslatableString("action", "Undo ‘%1’").arg(undoActionName));
     266              : 
     267            0 :     MenuItem& redoItem = findItem(REDO_COMMAND);
     268            0 :     const TranslatableString redoActionName = stack ? stack->topMostRedoActionName() : TranslatableString();
     269            0 :     redoItem.setTitle(redoActionName.isEmpty()
     270            0 :                       ? TranslatableString("action", "Redo")
     271            0 :                       : TranslatableString("action", "Redo ‘%1’").arg(redoActionName));
     272            0 : }
     273              : 
     274            0 : MenuItem* AppMenuModel::makeViewMenu()
     275              : {
     276              :     MenuItemList viewItems {
     277              : #ifndef Q_OS_MAC
     278            0 :         makeMenuItem(APP_FULLSCREEN_COMMAND),
     279              : #endif
     280            0 :         makeMenuItem(DOCK_TOGGLE_PALETTES_COMMAND),
     281            0 :         makeMenuItem(TOGGLE_MASTER_PALETTE_COMMAND),
     282            0 :         makeMenuItem(DOCK_TOGGLE_INSTRUMENTS_COMMAND),
     283            0 :         makeMenuItem(DOCK_TOGGLE_PROPERTIES_COMMAND),
     284            0 :         makeMenuItem(DOCK_TOGGLE_SELECTION_FILTER_COMMAND),
     285            0 :         makeMenuItem(DOCK_TOGGLE_UNDO_HISTORY_COMMAND),
     286            0 :         makeMenuItem(DOCK_TOGGLE_NAVIGATOR_COMMAND),
     287            0 :         makeMenuItem(DOCK_TOGGLE_BRAILLE_COMMAND),
     288            0 :         makeMenuItem(DOCK_TOGGLE_TIMELINE_COMMAND),
     289            0 :         makeMenuItem(DOCK_TOGGLE_MIXER_COMMAND),
     290            0 :         makeMenuItem(DOCK_TOGGLE_PIANO_KEYBOARD_COMMAND),
     291            0 :         makeMenuItem(DOCK_TOGGLE_PERCUSSION_COMMAND),
     292            0 :         makeMenuItem(OPEN_PLAYBACK_SETUP_COMMAND),
     293            0 :         makeSeparator(),
     294            0 :         makeMenu(TranslatableString("appshell/menu/view", "&Toolbars"), {
     295            0 :             makeMenuItem(DOCK_TOGGLE_PLAYBACK_COMMAND),
     296            0 :             makeMenuItem(DOCK_TOGGLE_NOTEINPUT_COMMAND),
     297            0 :             makeMenuItem(DOCK_TOGGLE_STATUSBAR_COMMAND)
     298              :         }, "menu-toolbars"),
     299              : #ifdef MUSE_MODULE_WORKSPACE
     300            0 :         makeMenu(TranslatableString("appshell/menu/view", "W&orkspaces"), m_workspacesMenuModel->items(), "menu-workspaces"),
     301              : #endif
     302            0 :         makeSeparator(),
     303            0 :         makeMenu(TranslatableString("appshell/menu/view", "&Show"), {
     304            0 :             makeMenuItem(SHOW_INVISIBLE_COMMAND),
     305            0 :             makeMenuItem(SHOW_UNPRINTABLE_COMMAND),
     306            0 :             makeMenuItem(SHOW_FRAMES_COMMAND),
     307            0 :             makeMenuItem(SHOW_PAGEBORDERS_COMMAND),
     308            0 :             makeMenuItem(SHOW_IRREGULAR_COMMAND),
     309            0 :             makeMenuItem(SHOW_SOUNDFLAGS_COMMAND),
     310              :         }, "menu-show"),
     311            0 :         makeSeparator(),
     312            0 :         makeMenuItem(DOCK_RESTORE_DEFAULT_LAYOUT_COMMAND),
     313            0 :     };
     314              : 
     315            0 :     return makeMenu(TranslatableString("appshell/menu/view", "&View"), viewItems, "menu-view");
     316            0 : }
     317              : 
     318            0 : MenuItem* AppMenuModel::makeAddMenu()
     319              : {
     320              :     MenuItemList addItems {
     321            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Notes"), makeNotesItems(), "menu-notes"),
     322            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Intervals"), makeIntervalsItems(), "menu-intervals"),
     323            0 :         makeMenu(TranslatableString("appshell/menu/add", "T&uplets"), makeTupletsItems(), "menu-tuplets"),
     324            0 :         makeSeparator(),
     325            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Measures"), makeMeasuresItems(), "menu-measures"),
     326            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Frames"), makeFramesItems(), "menu-frames"),
     327            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Text"), makeTextItems(), "menu-text"),
     328            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Lines"), makeLinesItems(), "menu-lines"),
     329            0 :         makeMenu(TranslatableString("appshell/menu/add", "&Chords and fretboard diagrams"),
     330            0 :                  makeChordAndFretboardDiagramsItems(), "menu-chord-and-frets"),
     331            0 :     };
     332              : 
     333            0 :     return makeMenu(TranslatableString("appshell/menu/add", "&Add"), addItems, "menu-add");
     334            0 : }
     335              : 
     336            0 : MenuItem* AppMenuModel::makeFormatMenu()
     337              : {
     338              :     MenuItemList formatItems {
     339            0 :         makeMenuItem(OPEN_EDIT_STYLE_COMMAND),
     340            0 :         makeMenuItem(OPEN_PAGE_SETTINGS_COMMAND),
     341            0 :         makeSeparator(),
     342            0 :         makeMenuItem(OPEN_BREAKS_COMMAND),
     343            0 :         makeMenu(TranslatableString("appshell/menu/format", "Str&etch"), {
     344            0 :             makeMenuItem(STRETCH_INCREASE_COMMAND),
     345            0 :             makeMenuItem(STRETCH_DECREASE_COMMAND),
     346            0 :             makeMenuItem(STRETCH_RESET_COMMAND)
     347              :         }, "menu-stretch"),
     348            0 :         makeSeparator(),
     349            0 :         makeMenuItem(RESET_TEXT_STYLE_OVERRIDES_COMMAND),
     350            0 :         makeMenuItem(RESET_BEAMS_COMMAND),
     351            0 :         makeMenuItem(RESET_SHAPES_AND_POSITIONS_COMMAND),
     352            0 :         makeMenuItem(RESET_TO_DEFAULT_LAYOUT_COMMAND),
     353            0 :         makeSeparator(),
     354            0 :         makeMenuItem(LOAD_STYLE_COMMAND),
     355            0 :         makeMenuItem(SAVE_STYLE_COMMAND)
     356            0 :     };
     357              : 
     358            0 :     return makeMenu(TranslatableString("appshell/menu/format", "F&ormat"), formatItems, "menu-format");
     359            0 : }
     360              : 
     361            0 : MenuItem* AppMenuModel::makeToolsMenu()
     362              : {
     363              :     MenuItemList toolsItems {
     364            0 :         makeMenuItem(OPEN_TRANSPOSE_COMMAND),
     365            0 :         makeSeparator(),
     366            0 :         makeMenuItem(STAFF_EXPLODE_COMMAND),
     367            0 :         makeMenuItem(STAFF_IMPLODE_COMMAND),
     368            0 :         makeMenuItem(OPEN_REALIZECHORDSYMBOLS_COMMAND),
     369            0 :         makeMenu(TranslatableString("appshell/menu/tools", "&Voices"), {
     370            0 :             makeMenuItem(SWAP_VOICE_X12_COMMAND),
     371            0 :             makeMenuItem(SWAP_VOICE_X13_COMMAND),
     372            0 :             makeMenuItem(SWAP_VOICE_X14_COMMAND),
     373            0 :             makeMenuItem(SWAP_VOICE_X23_COMMAND),
     374            0 :             makeMenuItem(SWAP_VOICE_X24_COMMAND),
     375            0 :             makeMenuItem(SWAP_VOICE_X34_COMMAND)
     376              :         }, "menu-voices"),
     377            0 :         makeMenu(TranslatableString("appshell/menu/tools", "&Measures"), {
     378            0 :             makeMenuItem(SPLIT_MEASURE_COMMAND),
     379            0 :             makeMenuItem(JOIN_MEASURES_COMMAND)
     380              :         }, "menu-tools-measures"),
     381            0 :         makeMenuItem(REMOVE_SELECTED_RANGE_COMMAND),
     382            0 :         makeSeparator(),
     383            0 :         makeMenuItem(SLASH_FILL_COMMAND),
     384            0 :         makeMenuItem(SLASH_RHYTHM_COMMAND),
     385            0 :         makeSeparator(),
     386            0 :         makeMenuItem(PITCH_SPELL_SHARPS_COMMAND),
     387            0 :         makeMenuItem(PITCH_SPELL_FLATS_COMMAND),
     388            0 :         makeMenu(TranslatableString("appshell/menu/tools", "Enharmonic spelling"), {
     389            0 :             makeMenuItem(ENHARMONIC_SPELL_BOTH_COMMAND),
     390            0 :             makeMenuItem(ENHARMONIC_SPELL_CURRENT_COMMAND),
     391            0 :             makeMenuItem(PITCH_SPELL_COMMAND),
     392              :         }, "menu-enharmonic-spelling"),
     393            0 :         makeSeparator(),
     394            0 :         makeMenuItem(REGROUP_RHYTHMS_COMMAND),
     395            0 :         makeMenuItem(RESEQUENCE_REHEARSAL_MARKS_COMMAND),
     396            0 :         makeSeparator(),
     397            0 :         makeMenuItem(COPY_LYRICS_COMMAND),
     398            0 :         makeMenuItem(REMOVE_EMPTY_TRAILING_MEASURES_COMMAND),
     399            0 :     };
     400              : 
     401            0 :     return makeMenu(TranslatableString("appshell/menu/tools", "&Tools"), toolsItems, "menu-tools");
     402            0 : }
     403              : 
     404            0 : muse::uicomponents::MenuItemList AppMenuModel::makeExtensionsSubitems()
     405              : {
     406              :     MenuItemList subitems {
     407            0 :         makeMenuItem(APP_EXTENSIONS_COMMAND),
     408            0 :     };
     409              : 
     410            0 :     MenuItemList extensions = makeExtensionsItems();
     411              : 
     412            0 :     if (!extensions.empty()) {
     413            0 :         subitems << makeSeparator();
     414              :     }
     415              : 
     416            0 :     subitems << extensions;
     417            0 :     return subitems;
     418            0 : }
     419              : 
     420            0 : MenuItem* AppMenuModel::makeExtensionsMenu()
     421              : {
     422            0 :     return makeMenu(TranslatableString("appshell/menu/plugins", "E&xtensions"), makeExtensionsSubitems(), "menu-extensions");
     423              : }
     424              : 
     425            0 : MenuItem* AppMenuModel::makeHelpMenu(bool addDiagnosticsSubMenu)
     426              : {
     427            0 :     MenuItemList helpItems;
     428              : 
     429            0 :     if (updateConfiguration()->isAppUpdatable()) {
     430            0 :         helpItems << makeMenuItem(UPDATE_CHECK_COMMAND);
     431            0 :         helpItems << makeSeparator();
     432              :     }
     433              : 
     434            0 :     helpItems << makeMenuItem(APP_ONLINE_HANDBOOK_COMMAND);
     435            0 :     helpItems << makeMenuItem(APP_ASK_HELP_COMMAND);
     436            0 :     helpItems << makeSeparator();
     437              : 
     438            0 :     if (addDiagnosticsSubMenu) {
     439            0 :         helpItems << makeDiagnosticsMenu();
     440            0 :         helpItems << makeSeparator();
     441              :     }
     442              : 
     443            0 :     helpItems << makeMenuItem(APP_ABOUT_MUSESCORE_COMMAND, MenuItemRole::AboutRole);
     444            0 :     helpItems << makeMenuItem(APP_ABOUT_QT_COMMAND, MenuItemRole::AboutQtRole);
     445            0 :     helpItems << makeMenuItem(APP_ABOUT_MUSICXML_COMMAND);
     446            0 :     helpItems << makeMenuItem(APP_ACCESSIBILITY_STATEMENT_COMMAND);
     447            0 :     helpItems << makeSeparator();
     448              : 
     449              : #if defined(Q_OS_WIN) || defined(Q_OS_MACOS)
     450              :     if (isMuseSamplerModuleAdded()) {
     451              :         helpItems << makeMenuItem(CLEAR_ONLINESOUNDS_CACHE_COMMAND);
     452              :         helpItems << makeSeparator();
     453              :     }
     454              : #endif
     455              : 
     456            0 :     helpItems << makeMenuItem(APP_REVERT_TO_FACTORY_COMMAND);
     457              : 
     458            0 :     return makeMenu(TranslatableString("appshell/menu/help", "&Help"), helpItems, "menu-help");
     459            0 : }
     460              : 
     461            0 : MenuItem* AppMenuModel::makeDiagnosticsMenu()
     462              : {
     463              :     MenuItemList items {
     464            0 :         makeMenuItem(DIAGNOSTICS_SAVE_FILES_COMMAND),
     465            0 :         makeMenuItem(RELOAD_PLAYBACK_CACHE_COMMAND),
     466            0 :         makeMenu(TranslatableString("appshell/menu/diagnostics", "&System"), {
     467            0 :             makeMenuItem(DIAGNOSTICS_SHOW_PATHS_COMMAND),
     468            0 :             makeMenuItem(DIAGNOSTICS_SHOW_GRAPHICSINFO_COMMAND),
     469            0 :             makeMenuItem(DIAGNOSTICS_SHOW_PROFILER_COMMAND),
     470              :         }, "menu-system")
     471            0 :     };
     472              : 
     473            0 :     if (isMuseSamplerModuleAdded()) {
     474              :         MenuItemList museSamplerItems {
     475            0 :             makeMenuItem(MUSESAMPLER_CHECK_COMMAND),
     476            0 :         };
     477              : 
     478            0 :         if (globalConfiguration()->devModeEnabled()) {
     479            0 :             museSamplerItems << makeMenuItem(MUSESAMPLER_RELOAD_COMMAND);
     480              :         }
     481              : 
     482            0 :         items << makeMenu(TranslatableString("appshell/menu/diagnostics", "&MuseSampler"), museSamplerItems, "menu-musesampler");
     483            0 :     }
     484              : 
     485            0 :     if (globalConfiguration()->devModeEnabled()) {
     486              :         MenuItemList actionsItems {
     487            0 :             makeMenuItem(DIAGNOSTICS_SHOW_ACTIONS_COMMAND),
     488            0 :             makeMenuItem(DIAGNOSTICS_SHOW_RCOMMANDS_COMMAND)
     489            0 :         };
     490              : 
     491              :         MenuItemList accessibilityItems {
     492            0 :             makeMenuItem(DIAGNOSTICS_SHOW_NAVIGATION_TREE_COMMAND),
     493            0 :             makeMenuItem(DIAGNOSTICS_SHOW_ACCESSIBLE_TREE_COMMAND),
     494            0 :             makeMenuItem(DIAGNOSTICS_DUMP_ACCESSIBLE_TREE_COMMAND),
     495            0 :         };
     496              : 
     497              :         MenuItemList engravingItems {
     498            0 :             makeMenuItem(DIAGNOSTICS_SHOW_ENGRAVING_ELEMENTS_COMMAND),
     499            0 :             makeMenuItem(DIAGNOSTICS_SHOW_ENGRAVING_UNDOSTACK_COMMAND),
     500            0 :             makeMenuItem(DIAGNOSTICS_SHOW_ENGRAVING_STYLE_COMMAND),
     501            0 :             makeSeparator(),
     502            0 :             makeMenuItem(SHOW_ELEMENT_BOUNDING_RECTS_COMMAND),
     503            0 :             makeMenuItem(COLOR_ELEMENT_SHAPES_COMMAND),
     504            0 :             makeMenuItem(SHOW_SEGMENT_SHAPES_COMMAND),
     505            0 :             makeMenuItem(COLOR_SEGMENT_SHAPES_COMMAND),
     506            0 :             makeMenuItem(SHOW_SKYLINES_COMMAND),
     507            0 :             makeMenuItem(SHOW_SYSTEM_BOUNDING_RECTS_COMMAND),
     508            0 :             makeMenuItem(SHOW_ELEMENT_MASKS_COMMAND),
     509            0 :             makeMenuItem(SHOW_GAP_RESTS_COMMAND),
     510            0 :             makeMenuItem(SHOW_LINE_ATTACH_POINTS_COMMAND),
     511            0 :             makeMenuItem(MARK_EMPTY_STAFF_COMMAND),
     512            0 :             makeMenuItem(SHOW_ORIGIN_AND_COMBINED_COMMAND),
     513            0 :             makeMenuItem(MARK_CORRUPTED_MEASURES_COMMAND),
     514            0 :             makeMenuItem(CHECK_FOR_SCORE_CORRUPTIONS_COMMAND)
     515            0 :         };
     516              : 
     517              :         MenuItemList extensionsItems {
     518            0 :             makeMenuItem(OPEN_APIDUMP_COMMAND),
     519            0 :         };
     520              : 
     521              :         MenuItemList testflowItems {
     522            0 :             makeMenuItem(TESTFLOW_OPEN_SCRIPTS_COMMAND),
     523            0 :         };
     524              : 
     525              : #ifdef MUSE_MODULE_VST
     526              :         MenuItemList vstItems {
     527            0 :             makeMenuItem(VST_USE_OLDVIEW_COMMAND),
     528            0 :             makeMenuItem(VST_USE_NEWVIEW_COMMAND),
     529            0 :         };
     530              : #endif
     531              : 
     532              :         MenuItemList audioItems {
     533            0 :             makeMenuItem(AUDIO_DEV_USE_DRIVER_MODE_COMMAND),
     534            0 :             makeMenuItem(AUDIO_DEV_USE_HYBRID_MODE_COMMAND),
     535            0 :         };
     536              : 
     537            0 :         items << makeMenu(TranslatableString("appshell/menu/diagnostics", "A&ctions"), actionsItems, "menu-diagnostics-actions")
     538            0 :               << makeMenu(TranslatableString("appshell/menu/diagnostics",
     539            0 :                                        "&Accessibility"), accessibilityItems, "menu-diagnostics-accessibility")
     540            0 :               << makeMenu(TranslatableString("appshell/menu/diagnostics", "&Engraving"), engravingItems, "menu-diagnostics-engraving")
     541            0 :               << makeMenu(TranslatableString("appshell/menu/diagnostics", "E&xtensions"), extensionsItems, "menu-diagnostics-extensions")
     542            0 :               << makeMenu(TranslatableString("appshell/menu/diagnostics", "&Testflow"), testflowItems, "menu-diagnostics-testflow");
     543              : 
     544              : #ifdef MUSE_MODULE_VST
     545            0 :         items << makeMenu(TranslatableString("appshell/menu/diagnostics", "&VST"), vstItems, "menu-diagnostics-vst");
     546              : #endif
     547              : 
     548            0 :         items << makeMenu(TranslatableString("appshell/menu/diagnostics", "&Audio"), audioItems, "menu-diagnostics-audio")
     549            0 :               << makeMenuItem(MULTIWINDOWS_DEV_SHOW_INFO_COMMAND);
     550            0 :     }
     551              : 
     552            0 :     return makeMenu(TranslatableString("appshell/menu/diagnostics", "&Diagnostics"), items, "menu-diagnostic");
     553            0 : }
     554              : 
     555            0 : MenuItemList AppMenuModel::makeRecentSubMenuItems()
     556              : {
     557            0 :     MenuItemList items;
     558            0 :     const RecentFilesList& recentFiles = recentFilesController()->recentFilesList();
     559              : 
     560            0 :     for (const RecentFile& file : recentFiles) {
     561            0 :         rcommand::CommandQuery query(PROJECT_OPEN_COMMAND);
     562            0 :         query.set("url", Val(file.path.toQUrl().toString().toStdString()));
     563            0 :         query.set("display_name", Val(file.displayNameOverride.toStdString()));
     564              : 
     565            0 :         MenuItem* item = new MenuItem(this);
     566            0 :         item->setCommandQuery(query);
     567            0 :         item->setTitle(TranslatableString::untranslatable(file.displayName(/*includingExtension*/ true)));
     568            0 :         item->setSelectable(true);
     569              : 
     570            0 :         bool isCloud = projectConfiguration()->isCloudProject(file.path);
     571            0 :         if (isCloud) {
     572            0 :             item->setIcon(IconCode::Code::CLOUD);
     573              :         }
     574              : 
     575            0 :         items << item;
     576            0 :     }
     577              : 
     578            0 :     if (!items.empty()) {
     579            0 :         items << makeSeparator()
     580            0 :               << makeMenuItem(PROJECT_CLEAR_RECENT_COMMAND);
     581              :     }
     582              : 
     583            0 :     return items;
     584            0 : }
     585              : 
     586            0 : MenuItemList AppMenuModel::makeNotesItems()
     587              : {
     588              :     MenuItemList items {
     589            0 :         makeMenuItem(TOGGLE_NOTE_INPUT_COMMAND),
     590            0 :         makeSeparator(),
     591            0 :         makeMenuItem(ENTER_NOTE_C_COMMAND),
     592            0 :         makeMenuItem(ENTER_NOTE_D_COMMAND),
     593            0 :         makeMenuItem(ENTER_NOTE_E_COMMAND),
     594            0 :         makeMenuItem(ENTER_NOTE_F_COMMAND),
     595            0 :         makeMenuItem(ENTER_NOTE_G_COMMAND),
     596            0 :         makeMenuItem(ENTER_NOTE_A_COMMAND),
     597            0 :         makeMenuItem(ENTER_NOTE_B_COMMAND),
     598            0 :         makeSeparator(),
     599            0 :         makeMenuItem(ADD_NOTE_C_COMMAND),
     600            0 :         makeMenuItem(ADD_NOTE_D_COMMAND),
     601            0 :         makeMenuItem(ADD_NOTE_E_COMMAND),
     602            0 :         makeMenuItem(ADD_NOTE_F_COMMAND),
     603            0 :         makeMenuItem(ADD_NOTE_G_COMMAND),
     604            0 :         makeMenuItem(ADD_NOTE_A_COMMAND),
     605            0 :         makeMenuItem(ADD_NOTE_B_COMMAND),
     606            0 :     };
     607              : 
     608            0 :     return items;
     609              : }
     610              : 
     611            0 : MenuItemList AppMenuModel::makeIntervalsItems()
     612              : {
     613              :     MenuItemList items {
     614            0 :         makeMenuItem(ADD_INTERVAL_PLUS_1_COMMAND),
     615            0 :         makeMenuItem(ADD_INTERVAL_PLUS_2_COMMAND),
     616            0 :         makeMenuItem(ADD_INTERVAL_PLUS_3_COMMAND),
     617            0 :         makeMenuItem(ADD_INTERVAL_PLUS_4_COMMAND),
     618            0 :         makeMenuItem(ADD_INTERVAL_PLUS_5_COMMAND),
     619            0 :         makeMenuItem(ADD_INTERVAL_PLUS_6_COMMAND),
     620            0 :         makeMenuItem(ADD_INTERVAL_PLUS_7_COMMAND),
     621            0 :         makeMenuItem(ADD_INTERVAL_PLUS_8_COMMAND),
     622            0 :         makeMenuItem(ADD_INTERVAL_PLUS_9_COMMAND),
     623            0 :         makeMenuItem(ADD_INTERVAL_PLUS_10_COMMAND),
     624            0 :         makeSeparator(),
     625            0 :         makeMenuItem(ADD_INTERVAL_MINUS_2_COMMAND),
     626            0 :         makeMenuItem(ADD_INTERVAL_MINUS_3_COMMAND),
     627            0 :         makeMenuItem(ADD_INTERVAL_MINUS_4_COMMAND),
     628            0 :         makeMenuItem(ADD_INTERVAL_MINUS_5_COMMAND),
     629            0 :         makeMenuItem(ADD_INTERVAL_MINUS_6_COMMAND),
     630            0 :         makeMenuItem(ADD_INTERVAL_MINUS_7_COMMAND),
     631            0 :         makeMenuItem(ADD_INTERVAL_MINUS_8_COMMAND),
     632            0 :         makeMenuItem(ADD_INTERVAL_MINUS_9_COMMAND),
     633            0 :         makeMenuItem(ADD_INTERVAL_MINUS_10_COMMAND)
     634            0 :     };
     635              : 
     636            0 :     return items;
     637              : }
     638              : 
     639            0 : MenuItemList AppMenuModel::makeTupletsItems()
     640              : {
     641              :     MenuItemList items {
     642            0 :         makeMenuItem(ADD_DUPLET_COMMAND),
     643            0 :         makeMenuItem(ADD_TRIPLET_COMMAND),
     644            0 :         makeMenuItem(ADD_QUADRUPLET_COMMAND),
     645            0 :         makeMenuItem(ADD_QUINTUPLET_COMMAND),
     646            0 :         makeMenuItem(ADD_SEXTUPLET_COMMAND),
     647            0 :         makeMenuItem(ADD_SEPTUPLET_COMMAND),
     648            0 :         makeMenuItem(ADD_OCTUPLET_COMMAND),
     649            0 :         makeMenuItem(ADD_NONUPLET_COMMAND),
     650            0 :         makeMenuItem(OPEN_TUPLET_CONFIGURE_COMMAND)
     651            0 :     };
     652              : 
     653            0 :     return items;
     654              : }
     655              : 
     656            0 : MenuItemList AppMenuModel::makeMeasuresItems()
     657              : {
     658              :     MenuItemList items {
     659            0 :         makeMenuItem(INSERT_MEASURE_COMMAND),
     660            0 :         makeMenuItem(APPEND_MEASURE_COMMAND),
     661            0 :         makeSeparator(),
     662            0 :         makeMenuItem(INSERT_MEASURES_COMMAND),
     663            0 :         makeMenuItem(INSERT_MEASURES_AFTER_SELECTION_COMMAND),
     664            0 :         makeSeparator(),
     665            0 :         makeMenuItem(INSERT_MEASURES_AT_START_OF_SCORE_COMMAND),
     666            0 :         makeMenuItem(APPEND_MEASURES_COMMAND)
     667            0 :     };
     668              : 
     669            0 :     return items;
     670              : }
     671              : 
     672            0 : MenuItemList AppMenuModel::makeFramesItems()
     673              : {
     674              :     MenuItemList items {
     675            0 :         makeMenuItem(INSERT_HBOX_COMMAND),
     676            0 :         makeMenuItem(INSERT_VBOX_COMMAND),
     677            0 :         makeMenuItem(INSERT_TEXTFRAME_COMMAND),
     678            0 :         makeMenuItem(INSERT_FRETFRAME_COMMAND),
     679            0 :         makeSeparator(),
     680            0 :         makeMenu(TranslatableString("notation", "Insert at end of score"), {
     681            0 :             makeMenuItem(APPEND_HBOX_COMMAND),
     682            0 :             makeMenuItem(APPEND_VBOX_COMMAND),
     683            0 :             makeMenuItem(APPEND_TEXTFRAME_COMMAND),
     684            0 :             makeMenuItem(APPEND_FRETFRAME_COMMAND)
     685              :         })
     686            0 :     };
     687              : 
     688            0 :     return items;
     689              : }
     690              : 
     691            0 : MenuItemList AppMenuModel::makeTextItems()
     692              : {
     693              :     MenuItemList items {
     694            0 :         makeMenuItem(ADD_TITLE_TEXT_COMMAND),
     695            0 :         makeMenuItem(ADD_SUBTITLE_TEXT_COMMAND),
     696            0 :         makeMenuItem(ADD_COMPOSER_TEXT_COMMAND),
     697            0 :         makeMenuItem(ADD_LYRICIST_TEXT_COMMAND),
     698            0 :         makeMenuItem(ADD_PART_TEXT_COMMAND),
     699            0 :         makeSeparator(),
     700            0 :         makeMenuItem(ADD_SYSTEM_TEXT_COMMAND),
     701            0 :         makeMenuItem(ADD_STAFF_TEXT_COMMAND),
     702            0 :         makeMenuItem(ADD_DYNAMIC_COMMAND),
     703            0 :         makeMenuItem(ADD_EXPRESSION_TEXT_COMMAND),
     704            0 :         makeMenuItem(ADD_REHEARSALMARK_TEXT_COMMAND),
     705            0 :         makeMenuItem(ADD_INSTRUMENT_CHANGE_TEXT_COMMAND),
     706            0 :         makeMenuItem(ADD_FINGERING_TEXT_COMMAND),
     707            0 :         makeSeparator(),
     708            0 :         makeMenuItem(ADD_STICKING_TEXT_COMMAND),
     709            0 :         makeMenuItem(ADD_CHORD_TEXT_COMMAND),
     710            0 :         makeMenuItem(ADD_ROMAN_NUMERAL_TEXT_COMMAND),
     711            0 :         makeMenuItem(ADD_NASHVILLE_NUMBER_TEXT_COMMAND),
     712            0 :         makeMenuItem(ADD_LYRICS_COMMAND),
     713            0 :         makeMenuItem(ADD_FIGURED_BASS_COMMAND),
     714            0 :         makeMenuItem(ADD_TEMPO_COMMAND)
     715            0 :     };
     716              : 
     717            0 :     return items;
     718              : }
     719              : 
     720            0 : MenuItemList AppMenuModel::makeLinesItems()
     721              : {
     722              :     MenuItemList items {
     723            0 :         makeMenuItem(ADD_SLUR_COMMAND),
     724            0 :         makeMenuItem(ADD_HAIRPIN_COMMAND),
     725            0 :         makeMenuItem(ADD_HAIRPIN_REVERSE_COMMAND),
     726            0 :         makeMenuItem(ADD_OTTAVA_8VA_COMMAND),
     727            0 :         makeMenuItem(ADD_OTTAVA_8VB_COMMAND),
     728            0 :         makeMenuItem(ADD_NOTELINE_COMMAND)
     729            0 :     };
     730              : 
     731            0 :     return items;
     732              : }
     733              : 
     734            0 : MenuItemList AppMenuModel::makeExtensionsItems()
     735              : {
     736            0 :     MenuItemList result;
     737              : 
     738            0 :     KnownCategories categories = extensionsRegister()->knownCategories();
     739            0 :     ManifestList manifests = extensionsRegister()->manifestList(Filter::Enabled);
     740              : 
     741            0 :     auto makeMenuItem = [this](const Manifest& m, const Action& a) {
     742            0 :         rcommand::Command command = makeCommand(m.uri, a.code);
     743            0 :         return this->makeMenuItem(command);
     744            0 :     };
     745              : 
     746            0 :     auto addMenuItems = [this, makeMenuItem](MenuItemList& items, const Manifest& m) {
     747            0 :         MenuItemList sub;
     748            0 :         for (const muse::extensions::Action& a : m.actions) {
     749            0 :             if (!a.showOnAppmenu) {
     750            0 :                 continue;
     751              :             }
     752            0 :             sub << makeMenuItem(m, a);
     753              :         }
     754              : 
     755            0 :         if (sub.empty()) {
     756            0 :             return;
     757              :         }
     758              : 
     759            0 :         if (sub.size() == 1) {
     760            0 :             items << sub.at(0);
     761            0 :             return;
     762              :         }
     763              : 
     764            0 :         items << makeMenu(TranslatableString::untranslatable(m.title), sub);
     765            0 :     };
     766              : 
     767            0 :     std::map<std::string, MenuItemList> categoriesMap;
     768            0 :     MenuItemList pluginsWithoutCategories;
     769            0 :     for (const Manifest& m : manifests) {
     770            0 :         std::string categoryStr = m.category.toStdString();
     771            0 :         if (!categoryStr.empty()) {
     772            0 :             if (!muse::contains(categories, categoryStr)) {
     773            0 :                 categories[categoryStr] = TranslatableString("extensions", m.category);
     774              :             }
     775            0 :             MenuItemList& items = categoriesMap[categoryStr];
     776            0 :             addMenuItems(items, m);
     777              :         } else {
     778            0 :             addMenuItems(pluginsWithoutCategories, m);
     779              :         }
     780            0 :     }
     781              : 
     782            0 :     for (const auto& it : categoriesMap) {
     783            0 :         TranslatableString categoryTitle = muse::value(categories, it.first, {});
     784            0 :         result << makeMenu(categoryTitle, it.second);
     785            0 :     }
     786              : 
     787            0 :     std::sort(result.begin(), result.end(), [](const MenuItem& l, const MenuItem& r) {
     788            0 :         return l.translatedTitle() < r.translatedTitle();
     789              :     });
     790              : 
     791            0 :     std::sort(pluginsWithoutCategories.begin(), pluginsWithoutCategories.end(), [](const MenuItem& l, const MenuItem& r) {
     792            0 :         return l.translatedTitle() < r.translatedTitle();
     793              :     });
     794              : 
     795            0 :     for (MenuItem* plugin : pluginsWithoutCategories) {
     796            0 :         result << plugin;
     797              :     }
     798              : 
     799            0 :     return result;
     800            0 : }
        

Generated by: LCOV version 2.0-1