LCOV - code coverage report
Current view: top level - src/engraving/api/v1 - selection.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 0.0 % 64 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              : #include "selection.h"
      24              : 
      25              : #include "engraving/editing/transaction/undostack.h"
      26              : 
      27              : // api
      28              : #include "score.h"
      29              : 
      30              : using namespace mu::engraving::apiv1;
      31              : 
      32              : //---------------------------------------------------------
      33              : //   QmlPlayEventsListAccess::append
      34              : //---------------------------------------------------------
      35              : 
      36            0 : Selection* mu::engraving::apiv1::selectionWrap(mu::engraving::Selection* selection)
      37              : {
      38            0 :     Selection* w = new Selection(selection);
      39              :     // All wrapper objects should belong to JavaScript code.
      40            0 :     QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
      41            0 :     return w;
      42              : }
      43              : 
      44              : //---------------------------------------------------------
      45              : //   Selection::checkSelectionIsNotLocked
      46              : //---------------------------------------------------------
      47              : 
      48            0 : bool Selection::checkSelectionIsNotLocked() const
      49              : {
      50            0 :     if (m_selection->isLocked()) {
      51            0 :         LOGW("Cannot change selection: %s", qPrintable(m_selection->lockReason()));
      52            0 :         return false;
      53              :     }
      54            0 :     return true;
      55              : }
      56              : 
      57              : //---------------------------------------------------------
      58              : //   Selection::select
      59              : ///   Selects the given element. At this point only a
      60              : ///   limited number of element types is supported, like
      61              : ///   notes, rests and most of text elements.
      62              : ///   \param e element to select
      63              : ///   \param add if \p true, appends an element to already
      64              : ///   existing selection. If \p false (default), deselects
      65              : ///   all other elements and selects this element.
      66              : ///   \return \p true on success, \p false if selection
      67              : ///   cannot be changed, e.g. due to the ongoing operation
      68              : ///   on a score (like dragging elements) or incorrect
      69              : ///   arguments to this function.
      70              : ///   \since MuseScore 3.5
      71              : //---------------------------------------------------------
      72              : 
      73            0 : bool Selection::select(EngravingItem* elWrapper, bool add)
      74              : {
      75            0 :     if (!checkSelectionIsNotLocked()) {
      76            0 :         return false;
      77              :     }
      78              : 
      79            0 :     if (!elWrapper) {
      80            0 :         return false;
      81              :     }
      82              : 
      83            0 :     mu::engraving::EngravingItem* e = elWrapper->element();
      84              : 
      85              :     // Check whether it's safe to select this element:
      86              :     // use types list from UndoableTransaction for now
      87            0 :     if (!mu::engraving::UndoableTransaction::canRecordSelectedElement(e)) {
      88            0 :         LOGW("Cannot select element of type %s", e->typeName());
      89            0 :         return false;
      90              :     }
      91              : 
      92            0 :     if (e->score() != m_selection->score() || elWrapper->ownership() != Ownership::SCORE) {
      93            0 :         LOGW("Selection::select: element does not belong to score");
      94            0 :         return false;
      95              :     }
      96              : 
      97            0 :     const SelectType selType = add ? SelectType::ADD : SelectType::SINGLE;
      98            0 :     e->score()->select(e, selType);
      99              : 
     100            0 :     return true;
     101              : }
     102              : 
     103              : //---------------------------------------------------------
     104              : //   Selection::selectRange
     105              : ///   Selects a range in a score
     106              : ///   \param startTick start tick to be included in selection
     107              : ///   \param endTick end tick of selection, excluded from selection
     108              : ///   \param startStaff start staff index, included in selection
     109              : ///   \param endStaff end staff index, excluded from selection
     110              : ///   \param startBox the Box at startTick to be included in selection
     111              : ///   \param endBox the Box at endTick to be included in selection
     112              : ///   \return \p true on success, \p false if selection
     113              : ///   cannot be changed, e.g. due to the ongoing operation
     114              : ///   on a score (like dragging elements) or incorrect
     115              : ///   arguments to this function.
     116              : ///   \since MuseScore 3.5
     117              : //---------------------------------------------------------
     118              : 
     119            0 : bool Selection::selectRange(int startTick, int endTick, int startStaff, int endStaff,
     120              :                             apiv1::MeasureBase* startBox, apiv1::MeasureBase* endBox)
     121              : {
     122            0 :     if (!checkSelectionIsNotLocked()) {
     123            0 :         return false;
     124              :     }
     125              : 
     126            0 :     const int nstaves = static_cast<int>(m_selection->score()->nstaves());
     127              : 
     128            0 :     startStaff = qBound(0, startStaff, nstaves - 1);
     129            0 :     endStaff = qBound(1, endStaff, nstaves);
     130              : 
     131            0 :     if (startStaff >= endStaff) {
     132            0 :         return false;
     133              :     }
     134              : 
     135            0 :     mu::engraving::Segment* segStart = m_selection->score()->tick2leftSegmentMM(mu::engraving::Fraction::fromTicks(startTick));
     136            0 :     mu::engraving::Segment* segEnd = m_selection->score()->tick2leftSegmentMM(mu::engraving::Fraction::fromTicks(endTick));
     137            0 :     if (!segStart) {
     138            0 :         return false;
     139              :     }
     140              : 
     141            0 :     if (segEnd && *segEnd < *segStart) {
     142            0 :         return false;
     143              :     }
     144              : 
     145            0 :     mu::engraving::Box* startBoxUnwrapped = nullptr;
     146            0 :     if (mu::engraving::EngravingItem* startBoxItem = startBox ? startBox->element() : nullptr) {
     147            0 :         startBoxUnwrapped = startBoxItem->isBox() ? toBox(startBoxItem) : nullptr;
     148            0 :         if (!startBoxUnwrapped) {
     149            0 :             LOGW() << "startBox has incorrect type";
     150              :         }
     151              :     }
     152              : 
     153            0 :     mu::engraving::Box* endBoxUnwrapped = nullptr;
     154            0 :     if (mu::engraving::EngravingItem* endBoxItem = endBox ? endBox->element() : nullptr) {
     155            0 :         endBoxUnwrapped = endBoxItem->isBox() ? toBox(endBoxItem) : nullptr;
     156            0 :         if (!endBoxUnwrapped) {
     157            0 :             LOGW() << "endBox has incorrect type";
     158              :         }
     159              :     }
     160              : 
     161            0 :     if (segEnd && m_selection->score()->undoStack()->hasActiveTransaction()) {
     162            0 :         m_selection->setRangeTicks(segStart->tick(), segEnd->tick(),
     163              :                                    startStaff, endStaff,
     164              :                                    startBoxUnwrapped, endBoxUnwrapped);
     165              :     } else {
     166            0 :         m_selection->setRange(segStart, segEnd,
     167              :                               startStaff, endStaff,
     168              :                               startBoxUnwrapped, endBoxUnwrapped);
     169              :     }
     170              : 
     171            0 :     return true;
     172              : }
     173              : 
     174              : //---------------------------------------------------------
     175              : //   Selection::deselect
     176              : ///   Deselects the given element.
     177              : ///   \return \p true on success, \p false if selection
     178              : ///   cannot be changed, e.g. due to the ongoing operation
     179              : ///   on a score (like dragging elements).
     180              : ///   \since MuseScore 3.5
     181              : //---------------------------------------------------------
     182              : 
     183            0 : bool Selection::deselect(EngravingItem* elWrapper)
     184              : {
     185            0 :     if (!checkSelectionIsNotLocked()) {
     186            0 :         return false;
     187              :     }
     188              : 
     189            0 :     if (!elWrapper) {
     190            0 :         return false;
     191              :     }
     192              : 
     193            0 :     m_selection->score()->deselect(elWrapper->element());
     194            0 :     return true;
     195              : }
     196              : 
     197              : //---------------------------------------------------------
     198              : //   Selection::clear
     199              : ///   Clears the selection.
     200              : ///   \return \p true on success, \p false if selection
     201              : ///   cannot be changed, e.g. due to the ongoing operation
     202              : ///   on a score (like dragging elements).
     203              : ///   \since MuseScore 3.5
     204              : //---------------------------------------------------------
     205              : 
     206            0 : bool Selection::clear()
     207              : {
     208            0 :     if (!checkSelectionIsNotLocked()) {
     209            0 :         return false;
     210              :     }
     211              : 
     212            0 :     m_selection->deselectAll();
     213            0 :     return true;
     214              : }
        

Generated by: LCOV version 2.0-1