LCOV - code coverage report
Current view: top level - src/engraving/api/v1 - score.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 23.5 % 311 73
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              : 
      23              : #include "score.h"
      24              : 
      25              : #include "compat/midi/compatmidirender.h"
      26              : #include "dom/factory.h"
      27              : #include "dom/instrtemplate.h"
      28              : #include "dom/measure.h"
      29              : #include "dom/scoreorder.h"
      30              : #include "dom/part.h"
      31              : #include "dom/score.h"
      32              : #include "dom/masterscore.h"
      33              : #include "dom/segment.h"
      34              : #include "dom/staff.h"
      35              : #include "dom/stafftype.h"
      36              : #include "dom/text.h"
      37              : #include "editing/editpart.h"
      38              : #include "editing/editsystemlocks.h"
      39              : #include "editing/transaction/transaction.h"
      40              : #include "types/typesconv.h"
      41              : 
      42              : #include "notation/inotation.h"
      43              : #include "notation/inotationinteraction.h" // IWYU pragma: keep
      44              : #include "notation/inotationundostack.h"
      45              : 
      46              : // api
      47              : #include "apistructs.h"
      48              : #include "cursor.h"
      49              : #include "elements.h"
      50              : #include "instrument.h"
      51              : #include "apitypes.h"
      52              : 
      53              : using namespace mu::engraving::apiv1;
      54              : 
      55            0 : Cursor* Score::newCursor()
      56              : {
      57            0 :     return new Cursor(score());
      58              : }
      59              : 
      60            0 : void Score::addText(const QString& type, const QString& txt)
      61              : {
      62            0 :     static const QMetaEnum meta = QMetaEnum::fromType<enums::TextStyleType>();
      63              : 
      64              :     mu::engraving::TextStyleType tid;
      65            0 :     const std::string key = type.toStdString();
      66            0 :     bool ok = false;
      67            0 :     int val = meta.keyToValue(key.c_str(), &ok);
      68            0 :     if (ok) {
      69            0 :         tid = static_cast<mu::engraving::TextStyleType>(val);
      70              :     } else {
      71            0 :         LOGE() << "Please use engraving::TextStyleType enum, the use of Xml tags is deprecated.";
      72            0 :         AsciiStringView t(key);
      73            0 :         tid = mu::engraving::TConv::fromXml(t, mu::engraving::TextStyleType::DEFAULT);
      74              :     }
      75              : 
      76            0 :     mu::engraving::MeasureBase* mb = score()->first();
      77            0 :     if (!mb || !mb->isVBox()) {
      78            0 :         score()->insertBox(ElementType::VBOX, mb);
      79            0 :         mb = score()->first();
      80              :     }
      81              : 
      82            0 :     mu::engraving::Text* text = mu::engraving::Factory::createText(mb, tid);
      83            0 :     text->setXmlText(txt);
      84            0 :     score()->undoAddElement(text);
      85            0 : }
      86              : 
      87              : //---------------------------------------------------------
      88              : //   defaultInstrTemplate
      89              : //---------------------------------------------------------
      90              : 
      91            0 : static const mu::engraving::InstrumentTemplate* defaultInstrTemplate()
      92              : {
      93            0 :     static mu::engraving::InstrumentTemplate defaultInstrument;
      94            0 :     if (defaultInstrument.channel.empty()) {
      95            0 :         mu::engraving::InstrChannel a;
      96            0 :         a.setChorus(0);
      97            0 :         a.setReverb(0);
      98            0 :         a.setName(muse::String::fromUtf8(mu::engraving::InstrChannel::DEFAULT_NAME));
      99            0 :         a.setBank(0);
     100            0 :         a.setVolume(90);
     101            0 :         a.setPan(0);
     102            0 :         defaultInstrument.channel.push_back(a);
     103            0 :     }
     104            0 :     return &defaultInstrument;
     105              : }
     106              : 
     107              : //---------------------------------------------------------
     108              : //   instrTemplateFromName
     109              : //---------------------------------------------------------
     110              : 
     111            0 : const mu::engraving::InstrumentTemplate* Score::instrTemplateFromName(const QString& name)
     112              : {
     113            0 :     const InstrumentTemplate* t = searchTemplate(name);
     114            0 :     if (!t) {
     115            0 :         LOGW("<%s> not found", qPrintable(name));
     116            0 :         t = defaultInstrTemplate();
     117              :     }
     118            0 :     return t;
     119              : }
     120              : 
     121            0 : mu::notation::INotationPtr Score::notation() const
     122              : {
     123            0 :     return projectSession()->currentNotation();
     124              : }
     125              : 
     126            0 : mu::notation::INotationUndoStackPtr Score::undoStack() const
     127              : {
     128            0 :     return notation() ? notation()->undoStack() : nullptr;
     129              : }
     130              : 
     131              : //---------------------------------------------------------
     132              : //   Score::appendPart
     133              : //---------------------------------------------------------
     134              : 
     135            0 : void Score::appendPart(const QString& instrumentId)
     136              : {
     137            0 :     const InstrumentTemplate* t = searchTemplate(instrumentId);
     138              : 
     139            0 :     if (!t) {
     140            0 :         LOGW("appendPart: <%s> not found", qPrintable(instrumentId));
     141            0 :         t = defaultInstrTemplate();
     142              :     }
     143              : 
     144            0 :     score()->appendPart(t);
     145            0 : }
     146              : 
     147              : //---------------------------------------------------------
     148              : //   Score::appendPartByMusicXmlId
     149              : //---------------------------------------------------------
     150              : 
     151            0 : void Score::appendPartByMusicXmlId(const QString& instrumentMusicXmlId)
     152              : {
     153            0 :     const InstrumentTemplate* t = searchTemplateForMusicXmlId(instrumentMusicXmlId);
     154              : 
     155            0 :     if (!t) {
     156            0 :         LOGW("appendPart: <%s> not found", qPrintable(instrumentMusicXmlId));
     157            0 :         t = defaultInstrTemplate();
     158              :     }
     159              : 
     160            0 :     score()->appendPart(t);
     161            0 : }
     162              : 
     163              : /** APIDOC
     164              : * Replaces the instrument for a given part with a new instrument.
     165              : * This changes the instrument definition including its name, clef, and sound.
     166              : * @method
     167              : * @param {Part} part - The Part object whose instrument should be replaced.
     168              : * @param {string} instrumentId - ID of the new instrument from instruments.xml.
     169              : */
     170            3 : void Score::replaceInstrument(apiv1::Part* part, const QString& instrumentId)
     171              : {
     172            3 :     if (!part) {
     173            1 :         LOGW("replaceInstrument: part is null");
     174            2 :         return;
     175              :     }
     176              : 
     177            2 :     const InstrumentTemplate* t = searchTemplate(instrumentId);
     178            2 :     if (!t) {
     179            1 :         LOGW("replaceInstrument: <%s> not found", qPrintable(instrumentId));
     180            1 :         return;
     181              :     }
     182              : 
     183            1 :     mu::engraving::Instrument newInstrument = mu::engraving::Instrument::fromTemplate(t);
     184            1 :     mu::engraving::EditPart::replacePartInstrument(score(), part->part(), newInstrument);
     185            1 : }
     186              : 
     187            1 : void Score::setPartVisible(apiv1::Part* part, bool visible)
     188              : {
     189            1 :     if (!part) {
     190            0 :         LOGW("setPartVisible: part is null");
     191            0 :         return;
     192              :     }
     193              : 
     194            1 :     mu::engraving::EditPart::setPartVisible(score(), part->part(), visible);
     195              : }
     196              : 
     197            0 : void Score::setPartSharpFlat(apiv1::Part* part, int sharpFlat)
     198              : {
     199            0 :     if (!part) {
     200            0 :         LOGW("setPartSharpFlat: part is null");
     201            0 :         return;
     202              :     }
     203              : 
     204            0 :     mu::engraving::EditPart::setPartSharpFlat(score(), part->part(), mu::engraving::PreferSharpFlat(sharpFlat));
     205              : }
     206              : 
     207            1 : void Score::setInstrumentName(apiv1::Part* part, apiv1::Fraction* tick, const QString& name)
     208              : {
     209            1 :     if (!part) {
     210            0 :         LOGW("setInstrumentName: part is null");
     211            0 :         return;
     212              :     }
     213            1 :     if (!tick) {
     214            0 :         LOGW("setInstrumentName: tick is null");
     215            0 :         return;
     216              :     }
     217              : 
     218            1 :     mu::engraving::EditPart::setInstrumentName(score(), part->part(), tick->fraction(), name);
     219              : }
     220              : 
     221            0 : void Score::setInstrumentAbbreviature(apiv1::Part* part, apiv1::Fraction* tick, const QString& abbreviature)
     222              : {
     223            0 :     if (!part) {
     224            0 :         LOGW("setInstrumentAbbreviature: part is null");
     225            0 :         return;
     226              :     }
     227            0 :     if (!tick) {
     228            0 :         LOGW("setInstrumentAbbreviature: tick is null");
     229            0 :         return;
     230              :     }
     231              : 
     232            0 :     mu::engraving::EditPart::setInstrumentAbbreviature(score(), part->part(), tick->fraction(), abbreviature);
     233              : }
     234              : 
     235            1 : void Score::setStaffType(apiv1::Staff* staff, int staffTypeId)
     236              : {
     237            1 :     if (!staff) {
     238            0 :         LOGW("setStaffType: staff is null");
     239            0 :         return;
     240              :     }
     241              : 
     242            1 :     mu::engraving::EditPart::setStaffType(score(), staff->staff(), mu::engraving::StaffTypes(staffTypeId));
     243              : }
     244              : 
     245            1 : void Score::removeParts(QList<apiv1::Part*> parts)
     246              : {
     247            1 :     std::vector<mu::engraving::Part*> domParts;
     248            2 :     for (apiv1::Part* p : parts) {
     249            1 :         if (!p) {
     250            0 :             LOGW("removeParts: null part in list");
     251            0 :             continue;
     252              :         }
     253            1 :         domParts.push_back(p->part());
     254              :     }
     255              : 
     256            1 :     mu::engraving::EditPart::removeParts(score(), domParts);
     257            1 : }
     258              : 
     259            0 : void Score::removeStaves(QList<apiv1::Staff*> staves)
     260              : {
     261            0 :     std::vector<mu::engraving::Staff*> domStaves;
     262            0 :     for (apiv1::Staff* s : staves) {
     263            0 :         if (!s) {
     264            0 :             LOGW("removeStaves: null staff in list");
     265            0 :             continue;
     266              :         }
     267            0 :         domStaves.push_back(s->staff());
     268              :     }
     269              : 
     270            0 :     mu::engraving::EditPart::removeStaves(score(), domStaves);
     271            0 : }
     272              : 
     273            1 : void Score::moveParts(QList<apiv1::Part*> sourceParts, apiv1::Part* destinationPart, int insertMode)
     274              : {
     275            1 :     if (!destinationPart) {
     276            0 :         LOGW("moveParts: destinationPart is null");
     277            0 :         return;
     278              :     }
     279              : 
     280            1 :     std::vector<mu::engraving::Part*> domParts;
     281            2 :     for (apiv1::Part* p : sourceParts) {
     282            1 :         if (!p) {
     283            0 :             LOGW("moveParts: null part in list");
     284            0 :             continue;
     285              :         }
     286            1 :         domParts.push_back(p->part());
     287              :     }
     288              : 
     289            1 :     mu::engraving::EditPart::moveParts(score(), domParts, destinationPart->part(), insertMode == 1);
     290            1 : }
     291              : 
     292            0 : void Score::moveStaves(QList<apiv1::Staff*> sourceStaves, apiv1::Staff* destinationStaff, int insertMode)
     293              : {
     294            0 :     if (!destinationStaff) {
     295            0 :         LOGW("moveStaves: destinationStaff is null");
     296            0 :         return;
     297              :     }
     298              : 
     299            0 :     std::vector<mu::engraving::Staff*> domStaves;
     300            0 :     for (apiv1::Staff* s : sourceStaves) {
     301            0 :         if (!s) {
     302            0 :             LOGW("moveStaves: null staff in list");
     303            0 :             continue;
     304              :         }
     305            0 :         domStaves.push_back(s->staff());
     306              :     }
     307              : 
     308            0 :     mu::engraving::EditPart::moveStaves(score(), domStaves, destinationStaff->staff(), insertMode == 1);
     309            0 : }
     310              : 
     311            0 : void Score::addSystemObjects(QList<apiv1::Staff*> staves)
     312              : {
     313            0 :     std::vector<mu::engraving::Staff*> domStaves;
     314            0 :     for (apiv1::Staff* s : staves) {
     315            0 :         if (!s) {
     316            0 :             LOGW("addSystemObjects: null staff in list");
     317            0 :             continue;
     318              :         }
     319            0 :         domStaves.push_back(s->staff());
     320              :     }
     321              : 
     322            0 :     mu::engraving::EditPart::addSystemObjects(score(), domStaves);
     323            0 : }
     324              : 
     325            0 : void Score::removeSystemObjects(QList<apiv1::Staff*> staves)
     326              : {
     327            0 :     std::vector<mu::engraving::Staff*> domStaves;
     328            0 :     for (apiv1::Staff* s : staves) {
     329            0 :         if (!s) {
     330            0 :             LOGW("removeSystemObjects: null staff in list");
     331            0 :             continue;
     332              :         }
     333            0 :         domStaves.push_back(s->staff());
     334              :     }
     335              : 
     336            0 :     mu::engraving::EditPart::removeSystemObjects(score(), domStaves);
     337            0 : }
     338              : 
     339            0 : void Score::moveSystemObjects(apiv1::Staff* sourceStaff, apiv1::Staff* destinationStaff)
     340              : {
     341            0 :     if (!sourceStaff) {
     342            0 :         LOGW("moveSystemObjects: sourceStaff is null");
     343            0 :         return;
     344              :     }
     345            0 :     if (!destinationStaff) {
     346            0 :         LOGW("moveSystemObjects: destinationStaff is null");
     347            0 :         return;
     348              :     }
     349              : 
     350            0 :     mu::engraving::EditPart::moveSystemObjects(score(), sourceStaff->staff(), destinationStaff->staff());
     351              : }
     352              : 
     353            1 : Staff* Score::appendStaff(Part* destinationPart)
     354              : {
     355            1 :     if (!destinationPart) {
     356            0 :         LOGW("appendStaff: destinationPart is null");
     357            0 :         return nullptr;
     358              :     }
     359              : 
     360            1 :     mu::engraving::Staff* staff = mu::engraving::EditPart::appendStaff(score(), destinationPart->part());
     361            1 :     return staff ? wrap<Staff>(staff, Ownership::SCORE) : nullptr;
     362              : }
     363              : 
     364            1 : Staff* Score::appendLinkedStaff(Staff* sourceStaff, Part* destinationPart)
     365              : {
     366            1 :     if (!sourceStaff) {
     367            0 :         LOGW("appendLinkedStaff: sourceStaff is null");
     368            0 :         return nullptr;
     369              :     }
     370            1 :     if (!destinationPart) {
     371            0 :         LOGW("appendLinkedStaff: destinationPart is null");
     372            0 :         return nullptr;
     373              :     }
     374              : 
     375            1 :     mu::engraving::Staff* staff = mu::engraving::EditPart::appendLinkedStaff(score(), sourceStaff->staff(), destinationPart->part());
     376            1 :     return staff ? wrap<Staff>(staff, Ownership::SCORE) : nullptr;
     377              : }
     378              : 
     379            1 : bool Score::setVoiceVisible(Staff* staff, int voiceIndex, bool visible)
     380              : {
     381            1 :     if (!staff) {
     382            0 :         LOGW("setVoiceVisible: staff is null");
     383            0 :         return false;
     384              :     }
     385              : 
     386            1 :     return mu::engraving::EditPart::setVoiceVisible(score(), staff->staff(), voiceIndex, visible);
     387              : }
     388              : 
     389            1 : void Score::replaceDrumset(Part* part, apiv1::Fraction* tick, Drumset* drumset)
     390              : {
     391            1 :     if (!part) {
     392            0 :         LOGW("replaceDrumset: part is null");
     393            0 :         return;
     394              :     }
     395            1 :     if (!tick) {
     396            0 :         LOGW("replaceDrumset: tick is null");
     397            0 :         return;
     398              :     }
     399            1 :     if (!drumset) {
     400            0 :         LOGW("replaceDrumset: drumset is null");
     401            0 :         return;
     402              :     }
     403              : 
     404            1 :     mu::engraving::EditPart::replaceDrumset(score(), part->part(), tick->fraction(), *drumset->drumset());
     405              : }
     406              : 
     407            1 : void Score::insertPart(const QString& instrumentId, int index)
     408              : {
     409            1 :     const InstrumentTemplate* t = searchTemplate(instrumentId);
     410            1 :     if (!t) {
     411            0 :         LOGW("insertPart: <%s> not found", qPrintable(instrumentId));
     412            0 :         return;
     413              :     }
     414              : 
     415            1 :     mu::engraving::EditPart::insertPart(score(), t, static_cast<size_t>(index));
     416              : }
     417              : 
     418            1 : void Score::replacePart(Part* part, const QString& instrumentId)
     419              : {
     420            1 :     if (!part) {
     421            0 :         LOGW("replacePart: part is null");
     422            0 :         return;
     423              :     }
     424              : 
     425            1 :     const InstrumentTemplate* t = searchTemplate(instrumentId);
     426            1 :     if (!t) {
     427            0 :         LOGW("replacePart: <%s> not found", qPrintable(instrumentId));
     428            0 :         return;
     429              :     }
     430              : 
     431            1 :     mu::engraving::EditPart::replacePart(score(), part->part(), t);
     432              : }
     433              : 
     434            1 : void Score::setScoreOrder(const QString& orderId)
     435              : {
     436            1 :     muse::String id = muse::String::fromQString(orderId);
     437              : 
     438            1 :     for (const mu::engraving::ScoreOrder& order : mu::engraving::instrumentOrders) {
     439            1 :         if (order.id == id) {
     440            1 :             mu::engraving::EditPart::setScoreOrder(score(), order);
     441            1 :             return;
     442              :         }
     443              :     }
     444              : 
     445            0 :     LOGW("setScoreOrder: <%s> not found", qPrintable(orderId));
     446            1 : }
     447              : 
     448              : //---------------------------------------------------------
     449              : //   Score::firstSegment
     450              : //---------------------------------------------------------
     451              : 
     452            0 : Segment* Score::firstSegment(int segmentType)
     453              : {
     454            0 :     return wrap<Segment>(score()->firstSegment(engraving::SegmentType(segmentType)), Ownership::SCORE);
     455              : }
     456              : 
     457            0 : Measure* Score::tick2measure(Fraction* f)
     458              : {
     459            0 :     const mu::engraving::Fraction tick = f->fraction();
     460            0 :     if (!tick.isValid() || tick.negative()) {
     461            0 :         return nullptr;
     462              :     }
     463            0 :     return wrap<Measure>(score()->tick2measure(tick));
     464              : }
     465              : 
     466            0 : Segment* Score::findSegmentAtTick(int segmentTypes, Fraction* f)
     467              : {
     468            0 :     const mu::engraving::Fraction tick = f->fraction();
     469            0 :     if (!tick.isValid() || tick.negative()) {
     470            0 :         return nullptr;
     471              :     }
     472            0 :     mu::engraving::Measure* measure = score()->tick2measure(tick);
     473            0 :     mu::engraving::Segment* segment = measure->findSegment(engraving::SegmentType(segmentTypes), tick);
     474            0 :     return segment ? wrap<Segment>(segment, Ownership::SCORE) : nullptr;
     475              : }
     476              : 
     477              : //---------------------------------------------------------
     478              : //   Score::lastSegment
     479              : //---------------------------------------------------------
     480              : 
     481            0 : Segment* Score::lastSegment()
     482              : {
     483            0 :     return wrap<Segment>(score()->lastSegment(), Ownership::SCORE);
     484              : }
     485              : 
     486              : //---------------------------------------------------------
     487              : //   Score::firstMeasure
     488              : //---------------------------------------------------------
     489              : 
     490            0 : Measure* Score::firstMeasure()
     491              : {
     492            0 :     return wrap<Measure>(score()->firstMeasure(), Ownership::SCORE);
     493              : }
     494              : 
     495              : //---------------------------------------------------------
     496              : //   Score::firstMeasureMM
     497              : //---------------------------------------------------------
     498              : 
     499            0 : Measure* Score::firstMeasureMM()
     500              : {
     501            0 :     return wrap<Measure>(score()->firstMeasureMM(), Ownership::SCORE);
     502              : }
     503              : 
     504              : //---------------------------------------------------------
     505              : //   Score::lastMeasure
     506              : //---------------------------------------------------------
     507              : 
     508            0 : Measure* Score::lastMeasure()
     509              : {
     510            0 :     return wrap<Measure>(score()->lastMeasure(), Ownership::SCORE);
     511              : }
     512              : 
     513              : //---------------------------------------------------------
     514              : //   Score::firstMeasureMM
     515              : //---------------------------------------------------------
     516              : 
     517            0 : Measure* Score::lastMeasureMM()
     518              : {
     519            0 :     return wrap<Measure>(score()->lastMeasureMM(), Ownership::SCORE);
     520              : }
     521              : 
     522            0 : QString Score::name() const
     523              : {
     524            0 :     return score()->masterScore()->name();
     525              : }
     526              : 
     527            0 : void Score::setName(const QString& /*name*/)
     528              : {
     529            0 :     NOT_IMPLEMENTED;
     530            0 : }
     531              : 
     532            0 : void Score::createPlayEvents()
     533              : {
     534            0 :     mu::engraving::CompatMidiRender::createPlayEvents(score());
     535            0 : }
     536              : 
     537            0 : QQmlListProperty<Staff> Score::staves() const
     538              : {
     539            0 :     return wrapContainerProperty<Staff>(this, score()->staves());
     540              : }
     541              : 
     542            0 : QQmlListProperty<Part> Score::parts() const
     543              : {
     544            0 :     return wrapContainerProperty<Part>(this, score()->parts());
     545              : }
     546              : 
     547            0 : QQmlListProperty<Excerpt> Score::excerpts() const
     548              : {
     549            0 :     return wrapExcerptsContainerProperty<Excerpt>(this, score()->masterScore()->excerpts());
     550              : }
     551              : 
     552            0 : QQmlListProperty<Page> Score::pages() const
     553              : {
     554            0 :     return wrapContainerProperty<Page>(this, score()->pages());
     555              : }
     556              : 
     557            0 : QQmlListProperty<System> Score::systems() const
     558              : {
     559            0 :     return wrapContainerProperty<System>(this, score()->systems());
     560              : }
     561              : 
     562            0 : QQmlListProperty<EngravingItem> Score::brackets(int staffIdx)
     563              : {
     564            0 :     return wrapContainerProperty<EngravingItem>(this, score()->brackets(static_cast<staff_idx_t>(staffIdx)));
     565              : }
     566              : 
     567            0 : bool Score::hasLyrics() const
     568              : {
     569            0 :     return score()->hasLyrics();
     570              : }
     571              : 
     572            0 : int Score::lyricCount() const
     573              : {
     574            0 :     return score()->lyricCount();
     575              : }
     576              : 
     577            0 : QQmlListProperty<Lyrics> Score::lyrics() const
     578              : {
     579            0 :     static std::vector<engraving::Lyrics*> list;
     580            0 :     list = score()->lyrics();
     581            0 :     return wrapContainerProperty<Lyrics>(this, list);
     582              : }
     583              : 
     584            0 : QString Score::extractLyrics() const
     585              : {
     586            0 :     return score()->extractLyrics();
     587              : }
     588              : 
     589            1 : QQmlListProperty<Spanner> Score::spanners()
     590              : {
     591            1 :     static std::vector<mu::engraving::Spanner*> spannerList;
     592            1 :     spannerList = score()->spannerList();
     593            1 :     return wrapContainerProperty<Spanner>(this, spannerList);
     594              : }
     595              : 
     596              : //---------------------------------------------------------
     597              : //   Score::startCmd
     598              : //---------------------------------------------------------
     599              : 
     600            0 : void Score::startCmd(const QString& qActionName)
     601              : {
     602            0 :     IF_ASSERT_FAILED(undoStack()) {
     603            0 :         return;
     604              :     }
     605              : 
     606            0 :     muse::TranslatableString actionName = qActionName.isEmpty()
     607            0 :                                           ? TranslatableString("undoableAction", "Plugin edit")
     608            0 :                                           : TranslatableString::untranslatable(qActionName);
     609              : 
     610            0 :     undoStack()->prepareChanges(actionName);
     611              :     // Lock the undo stack, so that all changes made by the plugin,
     612              :     // including PluginAPI::cmd(), are committed as a single command.
     613            0 :     undoStack()->lock();
     614            0 : }
     615              : 
     616            0 : void Score::endCmd(bool rollback)
     617              : {
     618            0 :     IF_ASSERT_FAILED(undoStack()) {
     619            0 :         return;
     620              :     }
     621              : 
     622            0 :     undoStack()->unlock();
     623              : 
     624            0 :     if (rollback) {
     625            0 :         undoStack()->rollbackChanges();
     626              :     } else {
     627            0 :         undoStack()->commitChanges();
     628              :     }
     629              : 
     630            0 :     notation()->notationChanged().send(muse::RectF());
     631              : }
     632              : 
     633            0 : void Score::doLayout(Fraction* startTick, Fraction* endTick)
     634              : {
     635            0 :     score()->doLayoutRange(startTick->fraction(), endTick->fraction());
     636            0 : }
     637              : 
     638            0 : void Score::addRemoveSystemLocks(int interval, bool lock)
     639              : {
     640            0 :     Transaction& tx = score()->transactionManager()->currentOrDummyTransaction();
     641            0 :     EditSystemLocks::addRemoveSystemLocks(tx, score(), interval, lock);
     642            0 : }
     643              : 
     644            0 : void Score::makeIntoSystem(apiv1::MeasureBase* first, apiv1::MeasureBase* last)
     645              : {
     646            0 :     Transaction& tx = score()->transactionManager()->currentOrDummyTransaction();
     647            0 :     EditSystemLocks::makeIntoSystem(tx, score(), first->measureBase(), last->measureBase());
     648            0 : }
     649              : 
     650            0 : void Score::showElementInScore(apiv1::EngravingItem* wrappedElement, int staffIdx)
     651              : {
     652            0 :     if (!wrappedElement->element()) {
     653            0 :         return;
     654              :     }
     655            0 :     notation()->interaction()->showItem(wrappedElement->element(), staffIdx);
     656              : }
        

Generated by: LCOV version 2.0-1