LCOV - code coverage report
Current view: top level - src/engraving/editing - editbeam.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 40.3 % 67 27
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) 2026 MuseScore Limited
       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 "editbeam.h"
      24              : 
      25              : #include "../dom/chordrest.h"
      26              : #include "../dom/groups.h"
      27              : #include "../dom/score.h"
      28              : #include "../dom/segment.h"
      29              : #include "../dom/select.h"
      30              : #include "../dom/utils.h"
      31              : 
      32              : #include "navigation.h"
      33              : 
      34              : #include "log.h"
      35              : 
      36              : using namespace mu::engraving;
      37              : 
      38              : //---------------------------------------------------------
      39              : //   setBeamMode
      40              : //---------------------------------------------------------
      41              : 
      42            5 : void EditBeam::setBeamMode(Transaction&, Score* score, BeamMode mode)
      43              : {
      44           10 :     for (ChordRest* cr : score->getSelectedChordRests()) {
      45            5 :         if (cr) {
      46            5 :             cr->undoChangeProperty(Pid::BEAM_MODE, mode);
      47              :         }
      48            5 :     }
      49            5 : }
      50              : 
      51              : //---------------------------------------------------------
      52              : //   beamSelectedRange
      53              : //---------------------------------------------------------
      54              : 
      55            0 : void EditBeam::beamSelectedRange(Transaction& tx, Score* score)
      56              : {
      57            0 :     if (!score->selection().isRange()) {
      58            0 :         return;
      59              :     }
      60              : 
      61            0 :     resetBeamMode(tx, score);
      62              : 
      63            0 :     const track_idx_t startTrack = staff2track(score->selection().staffStart());
      64            0 :     const track_idx_t endTrack = staff2track(score->selection().staffEnd());
      65            0 :     const SelectionFilter filter = score->selectionFilter();
      66              : 
      67            0 :     for (staff_idx_t trackIdx = startTrack; trackIdx < endTrack; ++trackIdx) {
      68            0 :         if (!filter.canSelectVoice(trackIdx)) {
      69            0 :             continue;
      70              :         }
      71              : 
      72            0 :         ChordRest* firstChordRest = score->selection().firstChordRest(trackIdx);
      73            0 :         ChordRest* lastChordRest = score->selection().lastChordRest(trackIdx);
      74              : 
      75            0 :         if (!firstChordRest || !lastChordRest) {
      76            0 :             continue;
      77              :         }
      78              : 
      79            0 :         ChordRest* prev = Navigation::prevChordRest(firstChordRest);
      80            0 :         ChordRest* cr = firstChordRest;
      81            0 :         BeamMode actualBeamMode = Groups::actualBeamMode(cr, prev);
      82            0 :         if (actualBeamMode != BeamMode::BEGIN) {
      83            0 :             cr->undoChangeProperty(Pid::BEAM_MODE, BeamMode::BEGIN);
      84              :         }
      85              : 
      86            0 :         while (cr != lastChordRest) {
      87            0 :             prev = cr;
      88            0 :             cr = Navigation::nextChordRest(cr);
      89            0 :             actualBeamMode = Groups::actualBeamMode(cr, prev);
      90            0 :             if (actualBeamMode == BeamMode::BEGIN || actualBeamMode == BeamMode::NONE) {
      91            0 :                 cr->undoChangeProperty(Pid::BEAM_MODE, BeamMode::MID);
      92              :             }
      93              :         }
      94              : 
      95            0 :         prev = cr;
      96            0 :         cr = Navigation::nextChordRest(cr);
      97            0 :         if (cr) {
      98            0 :             actualBeamMode = Groups::actualBeamMode(cr, prev);
      99            0 :             if (actualBeamMode != BeamMode::BEGIN && actualBeamMode != BeamMode::NONE) {
     100            0 :                 cr->undoChangeProperty(Pid::BEAM_MODE, BeamMode::BEGIN);
     101              :             }
     102              :         }
     103              :     }
     104              : }
     105              : 
     106              : //---------------------------------------------------------
     107              : //   resetBeamMode
     108              : //---------------------------------------------------------
     109              : 
     110            1 : void EditBeam::resetBeamMode(Transaction&, Score* score)
     111              : {
     112            1 :     bool noSelection = score->selection().isNone();
     113            1 :     if (noSelection) {
     114            1 :         score->cmdSelectAll();
     115            0 :     } else if (!score->selection().isRange()) {
     116            0 :         LOGD("no system or staff selected");
     117            0 :         return;
     118              :     }
     119              : 
     120            1 :     ChordRest* firstCr = score->selection().firstChordRest();
     121            1 :     if (!firstCr) {
     122            0 :         LOGD("no chord/rest in selection");
     123            0 :         return;
     124              :     }
     125              : 
     126            1 :     const track_idx_t trackStart = staff2track(score->selection().staffStart());
     127            1 :     const track_idx_t trackEnd = staff2track(score->selection().staffEnd());
     128            1 :     const Fraction endTick = score->selection().tickEnd();
     129            1 :     const SelectionFilter filter = score->selectionFilter();
     130              : 
     131            3 :     for (Segment* seg = firstCr->segment(); seg && seg->tick() < endTick; seg = seg->next1(SegmentType::ChordRest)) {
     132           10 :         for (track_idx_t track = trackStart; track < trackEnd; ++track) {
     133            8 :             if (!filter.canSelectVoice(track)) {
     134            0 :                 continue;
     135              :             }
     136              : 
     137            8 :             ChordRest* cr = toChordRest(seg->element(track));
     138            8 :             if (!cr) {
     139            6 :                 continue;
     140              :             }
     141            2 :             if (cr->isChord()) {
     142            2 :                 if (cr->beamMode() != BeamMode::AUTO) {
     143            2 :                     cr->undoChangeProperty(Pid::BEAM_MODE, BeamMode::AUTO);
     144              :                 }
     145            0 :             } else if (cr->isRest()) {
     146            0 :                 if (cr->beamMode() != BeamMode::NONE) {
     147            0 :                     cr->undoChangeProperty(Pid::BEAM_MODE, BeamMode::NONE);
     148              :                 }
     149              :             }
     150              :         }
     151              :     }
     152              : 
     153            1 :     if (noSelection) {
     154            1 :         score->deselectAll();
     155              :     }
     156              : }
        

Generated by: LCOV version 2.0-1