LCOV - code coverage report
Current view: top level - src/engraving/dom - capo.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 61.2 % 98 60
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) 2023 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 "capo.h"
      24              : 
      25              : #include "score.h"
      26              : 
      27              : #include "translation.h"
      28              : 
      29              : using namespace mu::engraving;
      30              : 
      31              : static const ElementStyle CAPO_STYLE {
      32              :     { Sid::staffTextPlacement, Pid::PLACEMENT },
      33              :     { Sid::staffTextMinDistance, Pid::MIN_DISTANCE },
      34              : };
      35              : 
      36           15 : Capo::Capo(DummyParentOr<Segment> parent, TextStyleType textStyleType)
      37           15 :     : StaffTextBase(ElementType::CAPO, parent, textStyleType, ElementFlag::MOVABLE | ElementFlag::ON_STAFF)
      38              : {
      39           15 :     initElementStyle(&CAPO_STYLE);
      40              : 
      41           15 :     m_params.active = true;
      42           15 :     m_params.fretPosition = 1;
      43           15 : }
      44              : 
      45            0 : Capo* Capo::clone() const
      46              : {
      47            0 :     return new Capo(*this);
      48              : }
      49              : 
      50           91 : PropertyValue Capo::getProperty(Pid id) const
      51              : {
      52           91 :     if (id == Pid::ACTIVE) {
      53            7 :         return m_params.active;
      54           84 :     } else if (id == Pid::CAPO_FRET_POSITION) {
      55            7 :         return m_params.fretPosition;
      56           77 :     } else if (id == Pid::CAPO_IGNORED_STRINGS) {
      57            0 :         std::vector<int> ignoredStrings;
      58            0 :         ignoredStrings.reserve(m_params.ignoredStrings.size());
      59            0 :         for (string_idx_t string : m_params.ignoredStrings) {
      60            0 :             ignoredStrings.push_back(static_cast<int>(string));
      61              :         }
      62            0 :         return ignoredStrings;
      63           77 :     } else if (id == Pid::CAPO_GENERATE_TEXT) {
      64            7 :         return m_shouldAutomaticallyGenerateText;
      65           70 :     } else if (id == Pid::CAPO_TRANSPOSE_MODE) {
      66            7 :         return m_params.transposeMode;
      67              :     }
      68              : 
      69           63 :     return StaffTextBase::getProperty(id);
      70              : }
      71              : 
      72           91 : PropertyValue Capo::propertyDefault(Pid id) const
      73              : {
      74           91 :     if (id == Pid::ACTIVE) {
      75            7 :         return true;
      76           84 :     } else if (id == Pid::CAPO_FRET_POSITION) {
      77            7 :         return 1;
      78           77 :     } else if (id == Pid::CAPO_IGNORED_STRINGS) {
      79            0 :         return std::vector<int>();
      80           77 :     } else if (id == Pid::CAPO_GENERATE_TEXT) {
      81            7 :         return true;
      82           70 :     } else if (id == Pid::CAPO_TRANSPOSE_MODE) {
      83           14 :         return CapoParams::TransposeMode::PLAYBACK_ONLY;
      84              :     }
      85              : 
      86           63 :     return StaffTextBase::propertyDefault(id);
      87              : }
      88              : 
      89          409 : bool Capo::setProperty(Pid id, const PropertyValue& val)
      90              : {
      91          409 :     if (id == Pid::ACTIVE) {
      92            0 :         m_params.active = val.toBool();
      93          409 :     } else if (id == Pid::CAPO_FRET_POSITION) {
      94            0 :         m_params.fretPosition = val.toInt();
      95          409 :     } else if (id == Pid::CAPO_IGNORED_STRINGS) {
      96            0 :         m_params.ignoredStrings.clear();
      97            0 :         auto ignoredStrings = val.value<std::vector<int> >();
      98            0 :         for (int string : ignoredStrings) {
      99            0 :             m_params.ignoredStrings.insert(static_cast<string_idx_t>(string));
     100              :         }
     101          409 :     } else if (id == Pid::CAPO_GENERATE_TEXT) {
     102            0 :         m_shouldAutomaticallyGenerateText = val.toBool();
     103              : 
     104            0 :         if (!m_shouldAutomaticallyGenerateText) {
     105            0 :             setXmlText(m_customText);
     106              :         }
     107          409 :     } else if (id == Pid::CAPO_TRANSPOSE_MODE) {
     108            3 :         m_params.transposeMode = val.value<CapoParams::TransposeMode>();
     109              :     } else {
     110          406 :         return StaffTextBase::setProperty(id, val);
     111              :     }
     112              : 
     113            3 :     triggerLayout();
     114              : 
     115            3 :     if (Score* s = score()) {
     116            3 :         s->updateCapo();
     117              :     }
     118              : 
     119            3 :     return true;
     120              : }
     121              : 
     122           52 : void Capo::setXmlText(const String& text)
     123              : {
     124           52 :     if (!m_shouldAutomaticallyGenerateText) {
     125            0 :         m_customText = text;
     126              :     }
     127              : 
     128           52 :     StaffTextBase::setXmlText(text);
     129           52 : }
     130              : 
     131            0 : bool Capo::isEditable() const
     132              : {
     133            0 :     return false;
     134              : }
     135              : 
     136           47 : const CapoParams& Capo::params() const
     137              : {
     138           47 :     return m_params;
     139              : }
     140              : 
     141           15 : void Capo::setParams(const CapoParams& params)
     142              : {
     143           15 :     m_params = params;
     144           15 : }
     145              : 
     146           44 : bool Capo::shouldAutomaticallyGenerateText() const
     147              : {
     148           44 :     return m_shouldAutomaticallyGenerateText;
     149              : }
     150              : 
     151           44 : muse::String Capo::generateText(size_t stringCount) const
     152              : {
     153           44 :     if (!m_params.active || m_params.fretPosition == 0) {
     154            0 :         return muse::mtrc("engraving", "No capo");
     155              :     }
     156              : 
     157           44 :     if (m_params.ignoredStrings.empty()) {
     158           44 :         return muse::mtrc("engraving", "Capo %1").arg(m_params.fretPosition);
     159              :     }
     160              : 
     161            0 :     StringList stringsToApply;
     162              : 
     163            0 :     for (string_idx_t idx = 0; idx < stringCount; ++idx) {
     164            0 :         if (muse::contains(m_params.ignoredStrings, idx)) {
     165            0 :             continue;
     166              :         }
     167              : 
     168            0 :         stringsToApply.emplace_back(String::number(idx + 1));
     169              :     }
     170              : 
     171            0 :     if (stringsToApply.empty()) {
     172            0 :         return muse::mtrc("engraving", "No capo");
     173              :     }
     174              : 
     175            0 :     String text = muse::mtrc("engraving", "Partial capo:\nFret %1 on strings %2")
     176            0 :                   .arg(m_params.fretPosition)
     177            0 :                   .arg(stringsToApply.join(u", "));
     178              : 
     179            0 :     return text;
     180            0 : }
     181              : 
     182           15 : void Capo::added()
     183              : {
     184           15 :     StaffTextBase::added();
     185              : 
     186           15 :     if (Score* s = score()) {
     187           15 :         s->updateCapo();
     188              :     }
     189           15 : }
     190              : 
     191            0 : void Capo::removed()
     192              : {
     193            0 :     StaffTextBase::removed();
     194              : 
     195            0 :     if (Score* s = score()) {
     196            0 :         s->updateCapo();
     197              :     }
     198            0 : }
        

Generated by: LCOV version 2.0-1