LCOV - code coverage report
Current view: top level - src/notationscene/qml/MuseScore/NotationScene - noteinputbarmodel.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 223 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 "noteinputbarmodel.h"
      23              : 
      24              : #include "rcommand/commandtypes.h"
      25              : #include "types/translatablestring.h"
      26              : 
      27              : #include "notation/inotationelements.h" // IWYU pragma: keep
      28              : #include "notation/inotationinteraction.h"
      29              : #include "notation/inotationnoteinput.h"
      30              : #include "notation/inotationselection.h"
      31              : #include "notation/inotationundostack.h"
      32              : 
      33              : #include "notationcommands.h"
      34              : 
      35              : using namespace mu;
      36              : using namespace mu::notation;
      37              : using namespace muse;
      38              : using namespace muse::ui;
      39              : using namespace muse::uicomponents;
      40              : 
      41              : static const QString TOOLBAR_NAME("noteInput");
      42              : 
      43              : const std::string NoteInputBarModel::CROSS_STAFF_BEAMING_SUBITEMS("cross-staff-beaming-subitems");
      44              : const std::string NoteInputBarModel::TUPLET_SUBITEMS("tuplets-subitems");
      45              : 
      46            0 : NoteInputBarModel::NoteInputBarModel(QObject* parent)
      47            0 :     : AbstractMenuModel(parent)
      48              : {
      49            0 : }
      50              : 
      51            0 : QVariant NoteInputBarModel::data(const QModelIndex& index, int role) const
      52              : {
      53            0 :     int row = index.row();
      54            0 :     if (!isIndexValid(row)) {
      55            0 :         return QVariant();
      56              :     }
      57              : 
      58            0 :     const MenuItem* item = items().at(row);
      59            0 :     switch (role) {
      60            0 :     case OrderRole: return row;
      61            0 :     case SectionRole: return item->section();
      62              :     }
      63              : 
      64            0 :     return AbstractMenuModel::data(index, role);
      65              : }
      66              : 
      67            0 : QHash<int, QByteArray> NoteInputBarModel::roleNames() const
      68              : {
      69            0 :     QHash<int, QByteArray> roles = AbstractMenuModel::roleNames();
      70            0 :     roles[OrderRole] = "order";
      71            0 :     roles[SectionRole] = "section";
      72              : 
      73            0 :     return roles;
      74            0 : }
      75              : 
      76            0 : void NoteInputBarModel::classBegin()
      77              : {
      78            0 :     init();
      79            0 : }
      80              : 
      81            0 : void NoteInputBarModel::init()
      82              : {
      83            0 :     subscribeOnChanges();
      84              : 
      85            0 :     uiState()->toolConfigChanged(TOOLBAR_NAME).onNotify(this, [this]() {
      86            0 :         load();
      87            0 :     });
      88              : 
      89            0 :     commandsController()->isNoteInputAllowedChanged().onReceive(this, [this](bool) {
      90            0 :         emit isInputAllowedChanged();
      91            0 :     });
      92              : 
      93            0 :     load();
      94            0 : }
      95              : 
      96            0 : const muse::ui::ToolConfig& NoteInputBarModel::defaultNoteInputConfig()
      97              : {
      98            0 :     static ToolConfig config;
      99            0 :     if (!config.isValid()) {
     100            0 :         config.items = {
     101              :             { TOGGLE_NOTE_INPUT_BY_NOTE_NAME_COMMAND, true },
     102              :             { TOGGLE_NOTE_INPUT_BY_DURATION_COMMAND, true },
     103              :             { TOGGLE_NOTE_INPUT_RHYTHM_COMMAND, false },
     104              :             { TOGGLE_NOTE_INPUT_REPITCH_COMMAND, false },
     105              :             { TOGGLE_NOTE_INPUT_REALTIME_AUTO_COMMAND, false },
     106              :             { TOGGLE_NOTE_INPUT_REALTIME_MANUAL_COMMAND, false },
     107              :             { TOGGLE_NOTE_INPUT_TIMEWISE_COMMAND, false },
     108              :             { ToolConfig::____________, true },
     109              :             { SET_DURATION_1024TH_COMMAND, false },
     110              :             { SET_DURATION_512TH_COMMAND, false },
     111              :             { SET_DURATION_256TH_COMMAND, false },
     112              :             { SET_DURATION_128TH_COMMAND, false },
     113              :             { SET_DURATION_64TH_COMMAND, true },
     114              :             { SET_DURATION_32ND_COMMAND, true },
     115              :             { SET_DURATION_16TH_COMMAND, true },
     116              :             { SET_DURATION_EIGHTH_COMMAND, true },
     117              :             { SET_DURATION_QUARTER_COMMAND, true },
     118              :             { SET_DURATION_HALF_COMMAND, true },
     119              :             { SET_DURATION_WHOLE_COMMAND, true },
     120              :             { SET_DURATION_BREVE_COMMAND, false },
     121              :             { SET_DURATION_LONGA_COMMAND, false },
     122              :             { ToolConfig::____________, true },
     123              :             { TOGGLE_DOT_COMMAND, true },
     124              :             { TOGGLE_DOT2_COMMAND, false },
     125              :             { TOGGLE_DOT3_COMMAND, false },
     126              :             { TOGGLE_DOT4_COMMAND, false },
     127              :             { TOGGLE_REST_COMMAND, true },
     128              :             { ToolConfig::____________, true },
     129              :             { TOGGLE_FLAT2_COMMAND, true },
     130              :             { TOGGLE_FLAT_COMMAND, true },
     131              :             { TOGGLE_NAT_COMMAND, true },
     132              :             { TOGGLE_SHARP_COMMAND, true },
     133              :             { TOGGLE_SHARP2_COMMAND, true },
     134              :             { ToolConfig::____________, true },
     135              :             { TOGGLE_TIE_COMMAND, true },
     136              :             { ADD_SLUR_COMMAND, true },
     137              :             { TOGGLE_LV_COMMAND, false },
     138              :             { ToolConfig::____________, true },
     139              :             { TOGGLE_MARCATO_COMMAND, true },
     140              :             { TOGGLE_SFORZATO_COMMAND, true },
     141              :             { TOGGLE_TENUTO_COMMAND, true },
     142              :             { TOGGLE_STACCATO_COMMAND, true },
     143              :             { ToolConfig::____________, true },
     144              :             { CROSS_STAFF_BEAMING_SUBITEMS, true }, // service
     145              :             { TUPLET_SUBITEMS, true },              // service
     146              :             { FlipCommand::id, true },
     147              :             { ToolConfig::____________, true },
     148              :             { USE_VOICE_1_COMMAND, true },
     149              :             { USE_VOICE_2_COMMAND, true },
     150              :             { USE_VOICE_3_COMMAND, false },
     151              :             { USE_VOICE_4_COMMAND, false }
     152            0 :         };
     153              :     }
     154            0 :     return config;
     155            0 : }
     156              : 
     157            0 : void NoteInputBarModel::load()
     158              : {
     159            0 :     MenuItemList items;
     160              : 
     161            0 :     ToolConfig noteInputConfig = uiState()->toolConfig(TOOLBAR_NAME, NoteInputBarModel::defaultNoteInputConfig());
     162              : 
     163            0 :     int section = 0;
     164            0 :     for (const ToolConfig::Item& citem : noteInputConfig.items) {
     165            0 :         if (!citem.show) {
     166            0 :             continue;
     167              :         }
     168              : 
     169            0 :         if (citem.isSeparator()) {
     170            0 :             section++;
     171            0 :             continue;
     172              :         }
     173              : 
     174            0 :         if (citem.intent == CROSS_STAFF_BEAMING_SUBITEMS) {
     175            0 :             MenuItem* item = makeServiceItem(CROSS_STAFF_BEAMING_SUBITEMS, QString::number(section));
     176            0 :             item->setSubitems(makeCrossStaffBeamingItems());
     177            0 :             items << item;
     178            0 :         } else if (citem.intent == TUPLET_SUBITEMS) {
     179            0 :             MenuItem* item = makeServiceItem(TUPLET_SUBITEMS, QString::number(section));
     180            0 :             item->setSubitems(makeTupletItems());
     181            0 :             items << item;
     182              :         } else {
     183            0 :             MenuItem* item = makeCommandItem(rcommand::Command(citem.intent), QString::number(section));
     184            0 :             items << item;
     185              :         }
     186              :     }
     187              : 
     188            0 :     items << makeAddItem(QString::number(++section));
     189            0 :     setItems(items);
     190            0 : }
     191              : 
     192            0 : bool NoteInputBarModel::isInputAllowed() const
     193              : {
     194            0 :     return commandsController()->isNoteInputAllowed();
     195              : }
     196              : 
     197            0 : NoteInputBarModel::ServiceItemInfo NoteInputBarModel::serviceItemInfo(const std::string& intent)
     198              : {
     199            0 :     if (intent == CROSS_STAFF_BEAMING_SUBITEMS) {
     200            0 :         return { TranslatableString("action", "Cross-staff beaming"), IconCode::Code::CROSS_STAFF_BEAMING };
     201            0 :     } else if (intent == TUPLET_SUBITEMS) {
     202            0 :         return { TranslatableString("action", "Tuplet"), IconCode::Code::NOTE_TUPLET };
     203              :     }
     204            0 :     return { };
     205            0 : }
     206              : 
     207            0 : MenuItem* NoteInputBarModel::makeServiceItem(const std::string& intent, const QString& section)
     208              : {
     209            0 :     const ServiceItemInfo info = serviceItemInfo(intent);
     210            0 :     MenuItem* item = new MenuItem(this);
     211            0 :     item->setTitle(info.title);
     212            0 :     item->setIcon(info.icon);
     213            0 :     item->setSection(section);
     214            0 :     return item;
     215            0 : }
     216              : 
     217            0 : MenuItem* NoteInputBarModel::makeCommandItem(const muse::rcommand::Command& command, const QString& section)
     218              : {
     219            0 :     const rcommand::CommandInfo info = commandsRegister()->commandInfo(command);
     220            0 :     MenuItem* item = new MenuItem(info, this);
     221            0 :     item->setSection(section);
     222            0 :     return item;
     223            0 : }
     224              : 
     225            0 : MenuItem* NoteInputBarModel::makeAddItem(const QString& section)
     226              : {
     227            0 :     MenuItem* item = new MenuItem(this);
     228            0 :     item->setTitle(TranslatableString("global", "Add"));
     229            0 :     item->setIcon(IconCode::Code::PLUS);
     230            0 :     item->setSection(section);
     231            0 :     item->setSubitems(makeAddItems());
     232            0 :     return item;
     233              : }
     234              : 
     235            0 : MenuItemList NoteInputBarModel::makeCrossStaffBeamingItems()
     236              : {
     237              :     MenuItemList items {
     238            0 :         makeMenuItem(MOVE_UP_COMMAND),
     239            0 :         makeMenuItem(MOVE_DOWN_COMMAND)
     240            0 :     };
     241              : 
     242            0 :     return items;
     243              : }
     244              : 
     245            0 : MenuItemList NoteInputBarModel::makeTupletItems()
     246              : {
     247              :     MenuItemList items {
     248            0 :         makeMenuItem(ADD_DUPLET_COMMAND),
     249            0 :         makeMenuItem(ADD_TRIPLET_COMMAND),
     250            0 :         makeMenuItem(ADD_QUADRUPLET_COMMAND),
     251            0 :         makeMenuItem(ADD_QUINTUPLET_COMMAND),
     252            0 :         makeMenuItem(ADD_SEXTUPLET_COMMAND),
     253            0 :         makeMenuItem(ADD_SEPTUPLET_COMMAND),
     254            0 :         makeMenuItem(ADD_OCTUPLET_COMMAND),
     255            0 :         makeMenuItem(ADD_NONUPLET_COMMAND),
     256            0 :         makeMenuItem(OPEN_TUPLET_CONFIGURE_COMMAND)
     257            0 :     };
     258              : 
     259            0 :     return items;
     260              : }
     261              : 
     262            0 : MenuItemList NoteInputBarModel::makeAddItems()
     263              : {
     264              :     MenuItemList items {
     265            0 :         makeMenu(TranslatableString("notation", "Notes"), makeNotesItems()),
     266            0 :         makeMenu(TranslatableString("notation", "Intervals"), makeIntervalsItems()),
     267            0 :         makeMenu(TranslatableString("notation", "Measures"), makeMeasuresItems()),
     268            0 :         makeMenu(TranslatableString("notation", "Frames"), makeFramesItems()),
     269            0 :         makeMenu(TranslatableString("notation", "Text"), makeTextItems()),
     270            0 :         makeMenu(TranslatableString("notation", "Lines"), makeLinesItems()),
     271            0 :         makeMenu(TranslatableString("notation", "Chords and fretboard diagrams"), makeChordAndFretboardDiagramsItems()),
     272            0 :     };
     273              : 
     274            0 :     return items;
     275              : }
     276              : 
     277            0 : MenuItemList NoteInputBarModel::makeNotesItems()
     278              : {
     279              :     MenuItemList items {
     280            0 :         makeMenuItem(ENTER_NOTE_C_COMMAND),
     281            0 :         makeMenuItem(ENTER_NOTE_D_COMMAND),
     282            0 :         makeMenuItem(ENTER_NOTE_E_COMMAND),
     283            0 :         makeMenuItem(ENTER_NOTE_F_COMMAND),
     284            0 :         makeMenuItem(ENTER_NOTE_G_COMMAND),
     285            0 :         makeMenuItem(ENTER_NOTE_A_COMMAND),
     286            0 :         makeMenuItem(ENTER_NOTE_B_COMMAND),
     287            0 :         makeSeparator(),
     288            0 :         makeMenuItem(ADD_NOTE_C_COMMAND),
     289            0 :         makeMenuItem(ADD_NOTE_D_COMMAND),
     290            0 :         makeMenuItem(ADD_NOTE_E_COMMAND),
     291            0 :         makeMenuItem(ADD_NOTE_F_COMMAND),
     292            0 :         makeMenuItem(ADD_NOTE_G_COMMAND),
     293            0 :         makeMenuItem(ADD_NOTE_A_COMMAND),
     294            0 :         makeMenuItem(ADD_NOTE_B_COMMAND)
     295            0 :     };
     296              : 
     297            0 :     return items;
     298              : }
     299              : 
     300            0 : MenuItemList NoteInputBarModel::makeIntervalsItems()
     301              : {
     302              :     MenuItemList items {
     303            0 :         makeMenuItem(ADD_INTERVAL_PLUS_1_COMMAND),
     304            0 :         makeMenuItem(ADD_INTERVAL_PLUS_2_COMMAND),
     305            0 :         makeMenuItem(ADD_INTERVAL_PLUS_3_COMMAND),
     306            0 :         makeMenuItem(ADD_INTERVAL_PLUS_4_COMMAND),
     307            0 :         makeMenuItem(ADD_INTERVAL_PLUS_5_COMMAND),
     308            0 :         makeMenuItem(ADD_INTERVAL_PLUS_6_COMMAND),
     309            0 :         makeMenuItem(ADD_INTERVAL_PLUS_7_COMMAND),
     310            0 :         makeMenuItem(ADD_INTERVAL_PLUS_8_COMMAND),
     311            0 :         makeMenuItem(ADD_INTERVAL_PLUS_9_COMMAND),
     312            0 :         makeMenuItem(ADD_INTERVAL_PLUS_10_COMMAND),
     313            0 :         makeSeparator(),
     314            0 :         makeMenuItem(ADD_INTERVAL_MINUS_2_COMMAND),
     315            0 :         makeMenuItem(ADD_INTERVAL_MINUS_3_COMMAND),
     316            0 :         makeMenuItem(ADD_INTERVAL_MINUS_4_COMMAND),
     317            0 :         makeMenuItem(ADD_INTERVAL_MINUS_5_COMMAND),
     318            0 :         makeMenuItem(ADD_INTERVAL_MINUS_6_COMMAND),
     319            0 :         makeMenuItem(ADD_INTERVAL_MINUS_7_COMMAND),
     320            0 :         makeMenuItem(ADD_INTERVAL_MINUS_8_COMMAND),
     321            0 :         makeMenuItem(ADD_INTERVAL_MINUS_9_COMMAND),
     322            0 :         makeMenuItem(ADD_INTERVAL_MINUS_10_COMMAND)
     323            0 :     };
     324              : 
     325            0 :     return items;
     326              : }
     327              : 
     328            0 : MenuItemList NoteInputBarModel::makeMeasuresItems()
     329              : {
     330              :     MenuItemList items {
     331            0 :         makeMenuItem(INSERT_MEASURES_COMMAND),
     332            0 :         makeMenuItem(APPEND_MEASURES_COMMAND),
     333            0 :         makeSeparator(),
     334            0 :         makeMenuItem(INSERT_MEASURES_COMMAND),
     335            0 :         makeMenuItem(INSERT_MEASURES_AFTER_SELECTION_COMMAND),
     336            0 :         makeSeparator(),
     337            0 :         makeMenuItem(INSERT_MEASURES_AT_START_OF_SCORE_COMMAND),
     338            0 :         makeMenuItem(APPEND_MEASURES_COMMAND)
     339            0 :     };
     340              : 
     341            0 :     return items;
     342              : }
     343              : 
     344            0 : MenuItemList NoteInputBarModel::makeFramesItems()
     345              : {
     346              :     MenuItemList items {
     347            0 :         makeMenuItem(INSERT_HBOX_COMMAND),
     348            0 :         makeMenuItem(INSERT_VBOX_COMMAND),
     349            0 :         makeMenuItem(INSERT_TEXTFRAME_COMMAND),
     350            0 :         makeMenuItem(INSERT_FRETFRAME_COMMAND),
     351            0 :         makeSeparator(),
     352            0 :         makeMenu(TranslatableString("notation", "Insert at end of score"), {
     353            0 :             makeMenuItem(APPEND_HBOX_COMMAND),
     354            0 :             makeMenuItem(APPEND_VBOX_COMMAND),
     355            0 :             makeMenuItem(APPEND_TEXTFRAME_COMMAND),
     356            0 :             makeMenuItem(APPEND_FRETFRAME_COMMAND)
     357              :         })
     358            0 :     };
     359              : 
     360            0 :     return items;
     361              : }
     362              : 
     363            0 : MenuItemList NoteInputBarModel::makeTextItems()
     364              : {
     365              :     MenuItemList items {
     366            0 :         makeMenuItem(ADD_TITLE_TEXT_COMMAND),
     367            0 :         makeMenuItem(ADD_SUBTITLE_TEXT_COMMAND),
     368            0 :         makeMenuItem(ADD_COMPOSER_TEXT_COMMAND),
     369            0 :         makeMenuItem(ADD_LYRICIST_TEXT_COMMAND),
     370            0 :         makeMenuItem(ADD_PART_TEXT_COMMAND),
     371            0 :         makeSeparator(),
     372            0 :         makeMenuItem(ADD_SYSTEM_TEXT_COMMAND),
     373            0 :         makeMenuItem(ADD_STAFF_TEXT_COMMAND),
     374            0 :         makeMenuItem(ADD_DYNAMIC_COMMAND),
     375            0 :         makeMenuItem(ADD_EXPRESSION_TEXT_COMMAND),
     376            0 :         makeMenuItem(ADD_REHEARSALMARK_TEXT_COMMAND),
     377            0 :         makeMenuItem(ADD_INSTRUMENT_CHANGE_TEXT_COMMAND),
     378            0 :         makeMenuItem(ADD_FINGERING_TEXT_COMMAND),
     379            0 :         makeSeparator(),
     380            0 :         makeMenuItem(ADD_STICKING_TEXT_COMMAND),
     381            0 :         makeMenuItem(ADD_CHORD_TEXT_COMMAND),
     382            0 :         makeMenuItem(ADD_ROMAN_NUMERAL_TEXT_COMMAND),
     383            0 :         makeMenuItem(ADD_NASHVILLE_NUMBER_TEXT_COMMAND),
     384            0 :         makeMenuItem(ADD_LYRICS_COMMAND),
     385            0 :         makeMenuItem(ADD_FIGURED_BASS_COMMAND),
     386            0 :         makeMenuItem(ADD_TEMPO_COMMAND)
     387            0 :     };
     388              : 
     389            0 :     return items;
     390              : }
     391              : 
     392            0 : MenuItemList NoteInputBarModel::makeLinesItems()
     393              : {
     394              :     MenuItemList items {
     395            0 :         makeMenuItem(ADD_SLUR_COMMAND),
     396            0 :         makeMenuItem(ADD_HAIRPIN_COMMAND),
     397            0 :         makeMenuItem(ADD_HAIRPIN_REVERSE_COMMAND),
     398            0 :         makeMenuItem(ADD_OTTAVA_8VA_COMMAND),
     399            0 :         makeMenuItem(ADD_OTTAVA_8VB_COMMAND),
     400            0 :         makeMenuItem(ADD_NOTELINE_COMMAND)
     401            0 :     };
     402              : 
     403            0 :     return items;
     404              : }
     405              : 
     406            0 : MenuItemList NoteInputBarModel::makeChordAndFretboardDiagramsItems()
     407              : {
     408              :     MenuItemList items {
     409            0 :         makeMenuItem(ADD_CHORD_TEXT_COMMAND),
     410            0 :         makeMenuItem(ADD_FRETBOARD_DIAGRAM_COMMAND),
     411            0 :         makeSeparator(),
     412            0 :         makeMenuItem(INSERT_FRETFRAME_COMMAND, TranslatableString("notation", "Fretboard diagram legend"))
     413            0 :     };
     414              : 
     415            0 :     return items;
     416              : }
        

Generated by: LCOV version 2.0-1