LCOV - code coverage report
Current view: top level - src/notationscene/utilities - percussionutilities.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 93 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) 2024 MuseScore Limited and others
       9              :  *
      10              :  * This program is free software: you can redistribute it and/or modify
      11              :  * it under the terms of the GNU General Public License version 3 as
      12              :  * published by the Free Software Foundation.
      13              :  *
      14              :  * This program is distributed in the hope that it will be useful,
      15              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      16              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17              :  * GNU General Public License for more details.
      18              :  *
      19              :  * You should have received a copy of the GNU General Public License
      20              :  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
      21              :  */
      22              : 
      23              : #include "percussionutilities.h"
      24              : 
      25              : #include "engraving/dom/chord.h"
      26              : #include "engraving/dom/factory.h"
      27              : #include "engraving/dom/masterscore.h"
      28              : #include "engraving/dom/note.h"
      29              : #include "engraving/dom/stem.h"
      30              : #include "engraving/rw/xmlreader.h"
      31              : 
      32              : using namespace mu::notation;
      33              : using namespace mu::engraving;
      34              : 
      35            0 : void PercussionUtilities::readDrumset(const muse::ByteArray& drumMapping, Drumset& drumset)
      36              : {
      37            0 :     XmlReader reader(drumMapping);
      38              : 
      39            0 :     while (reader.readNextStartElement()) {
      40            0 :         if (reader.name() == "museScore") {
      41            0 :             while (reader.readNextStartElement()) {
      42            0 :                 if (reader.name() == "Drum") {
      43            0 :                     drumset.loadDrum(reader);
      44            0 :                 } else if (reader.name() == "percussionPanelColumns") {
      45            0 :                     drumset.setPercussionPanelColumns(reader.readInt());
      46              :                 } else {
      47            0 :                     reader.unknown();
      48              :                 }
      49              :             }
      50              :         }
      51              :     }
      52            0 : }
      53              : 
      54              : /// Returns a drum note prepared for preview.
      55            0 : std::shared_ptr<Chord> PercussionUtilities::getDrumNoteForPreview(const Drumset* drumset, int pitch)
      56              : {
      57            0 :     double _spatium = paletteScoreProvider()->paletteScore()->style().spatium(); // TODO: Don't use palette here?
      58              : 
      59            0 :     bool up = false;
      60            0 :     int line = drumset->line(pitch);
      61            0 :     NoteHeadGroup noteHead = drumset->noteHead(pitch);
      62            0 :     int voice = drumset->voice(pitch);
      63            0 :     DirectionV dir = drumset->stemDirection(pitch);
      64              : 
      65            0 :     if (dir == DirectionV::UP) {
      66            0 :         up = true;
      67            0 :     } else if (dir == DirectionV::DOWN) {
      68            0 :         up = false;
      69              :     } else {
      70            0 :         up = line > 4;
      71              :     }
      72              : 
      73            0 :     auto chord = Factory::makeChord(paletteScoreProvider()->paletteScore()->dummy());
      74            0 :     chord->setDurationType(DurationType::V_QUARTER);
      75            0 :     chord->setStemDirection(dir);
      76            0 :     chord->setIsUiItem(true);
      77            0 :     chord->setTrack(voice);
      78              : 
      79            0 :     Note* note = Factory::createNote(chord.get());
      80            0 :     note->setMark(true);
      81            0 :     note->setTrack(voice);
      82            0 :     note->setPitch(pitch);
      83            0 :     note->setTpcFromPitch();
      84            0 :     note->setLine(line);
      85            0 :     note->setPos(0.0, _spatium * .5 * line);
      86            0 :     note->setHeadGroup(noteHead);
      87              : 
      88            0 :     SymId noteheadSym = SymId::noteheadBlack;
      89            0 :     if (noteHead == NoteHeadGroup::HEAD_CUSTOM) {
      90            0 :         noteheadSym = drumset->noteHeads(pitch, NoteHeadType::HEAD_QUARTER);
      91              :     } else {
      92            0 :         noteheadSym = note->noteHead(true, noteHead, NoteHeadType::HEAD_QUARTER);
      93              :     }
      94              : 
      95            0 :     note->mutldata()->cachedNoteheadSym.set_value(noteheadSym); // we use the cached notehead so we don't recompute it at each layout
      96            0 :     chord->add(note);
      97              : 
      98            0 :     Stem* stem = Factory::createStem(chord.get());
      99            0 :     stem->setBaseLength(up ? -3.0_sp : 3.0_sp);
     100            0 :     engravingRender()->layoutItem(stem);
     101            0 :     chord->add(stem);
     102              : 
     103            0 :     return chord;
     104            0 : }
     105              : 
     106              : /// Opens the percussion shortcut dialog, modifies drumset with user input
     107            0 : bool PercussionUtilities::editPercussionShortcut(Drumset& drumset, int originPitch)
     108              : {
     109            0 :     IF_ASSERT_FAILED(drumset.isValid(originPitch)) {
     110            0 :         return false;
     111              :     }
     112              : 
     113            0 :     const muse::RetVal<muse::Val> rv = openPercussionShortcutDialog(drumset, originPitch);
     114            0 :     if (!rv.ret) {
     115            0 :         return false;
     116              :     }
     117              : 
     118            0 :     const QVariantMap vals = rv.val.toQVariant().toMap();
     119              : 
     120            0 :     drumset.drum(originPitch).shortcut = vals.value("newShortcut").toString();
     121              : 
     122            0 :     const int conflictShortcutPitch = vals.value("conflictDrumPitch").toInt();
     123            0 :     if (drumset.isValid(conflictShortcutPitch)) {
     124            0 :         drumset.drum(conflictShortcutPitch).shortcut.clear();
     125              :     }
     126              : 
     127            0 :     return true;
     128            0 : }
     129              : 
     130            0 : muse::RetVal<muse::Val> PercussionUtilities::openPercussionShortcutDialog(const Drumset& drumset, int originPitch)
     131              : {
     132            0 :     muse::UriQuery query("musescore://notation/editpercussionshortcut?modal=true");
     133              : 
     134            0 :     const mu::engraving::DrumInstrument& originDrum = drumset.drum(originPitch);
     135            0 :     query.addParam("originDrum", muse::Val::fromQVariant(drumToQVariantMap(originPitch, originDrum)));
     136              : 
     137            0 :     QVariantList drumsWithShortcut;
     138            0 :     for (int otherPitch = 0; otherPitch < mu::engraving::DRUM_INSTRUMENTS; ++otherPitch) {
     139            0 :         if (otherPitch == originPitch || !drumset.isValid(otherPitch) || drumset.shortcut(otherPitch).isEmpty()) {
     140            0 :             continue;
     141              :         }
     142            0 :         QVariantMap drumVariant = drumToQVariantMap(otherPitch, drumset.drum(otherPitch));
     143            0 :         drumsWithShortcut << drumVariant;
     144            0 :     }
     145            0 :     query.addParam("drumsWithShortcut", muse::Val::fromQVariant(drumsWithShortcut));
     146              : 
     147            0 :     QVariantList applicationShortcuts;
     148            0 :     muse::shortcuts::ShortcutList shortcuts = commandShortcutsRegister()->shortcuts();
     149            0 :     for (const muse::shortcuts::Shortcut& shortcut : shortcuts) {
     150            0 :         const auto& info = commandsRegister()->commandInfo(shortcut.command);
     151            0 :         for (const std::string& str : shortcut.sequences) {
     152            0 :             QVariantMap sc;
     153            0 :             sc ["title"] = info.title.qTranslatedWithoutMnemonic();
     154            0 :             sc ["shortcut"] = QString::fromStdString(str);
     155            0 :             applicationShortcuts << sc;
     156            0 :         }
     157              :     }
     158            0 :     query.addParam("applicationShortcuts", muse::Val::fromQVariant(applicationShortcuts));
     159              : 
     160            0 :     return interactive()->openSync(query);
     161            0 : }
     162              : 
     163            0 : QVariantMap PercussionUtilities::drumToQVariantMap(int pitch, const engraving::DrumInstrument& drum)
     164              : {
     165            0 :     QVariantMap qv;
     166            0 :     qv["pitch"] = pitch;
     167            0 :     qv["title"] = drum.name.toQString();
     168            0 :     qv["shortcut"] = drum.shortcut.toQString();
     169            0 :     return qv;
     170            0 : }
        

Generated by: LCOV version 2.0-1