LCOV - code coverage report
Current view: top level - src/engraving/dom - unrollrepeats.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 68 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              : 
      23              : /**
      24              :  File handling: loading and saving.
      25              :  */
      26              : 
      27              : #include "style/style.h"
      28              : #include "../editing/editexcerpt.h"
      29              : #include "../editing/transaction/transaction.h"
      30              : 
      31              : #include "barline.h"
      32              : #include "engravingitem.h"
      33              : #include "excerpt.h"
      34              : #include "masterscore.h"
      35              : #include "measure.h"
      36              : #include "measurebase.h"
      37              : #include "part.h"
      38              : #include "repeatlist.h"
      39              : #include "score.h"
      40              : #include "segment.h"
      41              : 
      42              : #include "log.h"
      43              : 
      44              : namespace mu::engraving {
      45            0 : static void removeRepeatMarkings(Score* score)
      46              : {
      47              :     // remove bar-level repeats
      48            0 :     for (Measure* m = score->firstMeasure(); m; m = m->nextMeasure()) {
      49            0 :         m->setRepeatStart(false);
      50            0 :         m->setRepeatEnd(false);
      51              :     }
      52              : 
      53              :     // remove volta markers
      54            0 :     auto smap = score->spannerMap().map();
      55            0 :     for (auto it = smap.cbegin(); it != smap.cend(); ++it) {
      56            0 :         Spanner* s = (*it).second;
      57            0 :         if (!s || !s->isVolta()) {
      58            0 :             continue;
      59              :         }
      60            0 :         score->removeSpanner(s);
      61              :     }
      62              : 
      63              :     // remove coda/fine labels and jumps
      64            0 :     std::vector<EngravingItem*> elems = score->getChildren(false);
      65            0 :     for (auto e : elems) {
      66            0 :         if (e->isMarker() || e->isJump()) {
      67            0 :             score->deleteItem(e);
      68            0 :         } else if (e->isBarLine()) {
      69            0 :             toBarLine(e)->setBarLineType(BarLineType::NORMAL);
      70              :         }
      71              :     }
      72              : 
      73              :     // set the last bar line to end symbol
      74            0 :     score->lastMeasure()->setEndBarLineType(BarLineType::END, false);
      75            0 :     Segment* last = score->lastMeasure()->segments().last();
      76            0 :     if (last->segmentType() == SegmentType::EndBarLine) {
      77            0 :         auto els = last->elist();
      78            0 :         for (size_t i = 0; i < els.size(); i++) {
      79            0 :             if (!els[i]) {
      80            0 :                 continue;
      81              :             }
      82            0 :             toBarLine(els[i])->setBarLineType(BarLineType::END);
      83              :         }
      84            0 :     }
      85            0 : }
      86              : 
      87              : //---------------------------------------------------------
      88              : //   createExcerpts
      89              : //    re-create all the excerpts once the master score
      90              : //    has been unrolled
      91              : //---------------------------------------------------------
      92              : 
      93            0 : static void createExcerpts(MasterScore* cs, const std::vector<Excerpt*>& excerpts)
      94              : {
      95              :     // borrowed from musescore.cpp endsWith(".pdf")
      96            0 :     for (Excerpt* e : excerpts) {
      97            0 :         Score* nscore = e->masterScore()->createScore();
      98            0 :         e->setExcerptScore(nscore);
      99            0 :         nscore->style().set(Sid::createMultiMeasureRests, true);
     100            0 :         cs->transactionManager()->transaction(TranslatableString("undoableAction", "Create parts"), [&](auto& tx) {
     101            0 :             tx.push(new AddExcerpt(e));
     102            0 :             Excerpt::createExcerpt(e);
     103              : 
     104              :             // borrowed from excerptsdialog.cpp
     105              :             // a new excerpt is created in AddExcerpt, make sure the parts are filed
     106            0 :             for (Excerpt* ee : e->masterScore()->excerpts()) {
     107            0 :                 if (ee->excerptScore() == nscore && ee != e) {
     108            0 :                     ee->parts().clear();
     109            0 :                     ee->parts().insert(ee->parts().end(), e->parts().begin(), e->parts().end());
     110              :                 }
     111              :             }
     112            0 :         });
     113              :     }
     114            0 : }
     115              : 
     116              : //---------------------------------------------------------
     117              : //   unrollRepeats
     118              : //    unroll all the repeats
     119              : //---------------------------------------------------------
     120              : 
     121            0 : MasterScore* MasterScore::unrollRepeats()
     122              : {
     123            0 :     MasterScore* original = this;
     124              : 
     125              :     // create a copy of the original score to play with
     126            0 :     MasterScore* score = original->clone();
     127              : 
     128              :     // if no repeats, just return the score as-is
     129            0 :     const RepeatList& expandedRepeats = original->expandedRepeatList();
     130            0 :     if (expandedRepeats.size() == 1) {
     131            0 :         return score;
     132              :     }
     133              : 
     134              :     // remove excerpts for now (they are re-created after unrolling master score)
     135            0 :     std::vector<Excerpt*> excerpts;
     136            0 :     excerpts.reserve(score->excerpts().size());
     137            0 :     for (Excerpt* e : score->excerpts()) {
     138            0 :         excerpts.push_back(new Excerpt(*e, false));
     139            0 :         score->masterScore()->deleteExcerpt(e);
     140              :     }
     141              : 
     142              :     // follow along with the repeatList
     143            0 :     bool first = true;
     144            0 :     for (const RepeatSegment* rs: expandedRepeats) {
     145            0 :         Fraction startTick = Fraction::fromTicks(rs->tick);
     146            0 :         Fraction endTick   = Fraction::fromTicks(rs->endTick());
     147              : 
     148              :         // first segment left from clone, everything past that removed
     149            0 :         if (first) {
     150            0 :             if (endTick <= score->lastMeasure()->tick()) {     // check if we actually need to remove any measures
     151            0 :                 score->deleteMeasures(score->tick2measure(endTick), score->lastMeasure());
     152              :             }
     153            0 :             first = false;
     154              :         } else {  // just append this section from the original to the new score
     155            0 :             score->appendMeasuresFromScore(original, startTick, endTick);
     156              :         }
     157              :     }
     158              : 
     159            0 :     removeRepeatMarkings(score);
     160              : 
     161            0 :     score->updateTicksAndTimeSigMap();
     162              : 
     163            0 :     score->setLayoutAll();
     164            0 :     score->doLayout();
     165              : 
     166              :     // re-create excerpt parts
     167            0 :     if (!excerpts.empty()) {
     168            0 :         createExcerpts(score, excerpts);
     169              :     }
     170              : 
     171            0 :     return score;
     172            0 : }
     173              : }
        

Generated by: LCOV version 2.0-1