LCOV - code coverage report
Current view: top level - src/engraving/dom - marker.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 69.6 % 102 71
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 "marker.h"
      24              : 
      25              : #include "dom/staff.h"
      26              : #include "dom/system.h"
      27              : #include "types/typesconv.h"
      28              : 
      29              : #include "measure.h"
      30              : #include "score.h"
      31              : 
      32              : #include "log.h"
      33              : 
      34              : using namespace mu;
      35              : using namespace mu::engraving;
      36              : 
      37              : namespace mu::engraving {
      38              : //---------------------------------------------------------
      39              : //   markerStyle
      40              : //---------------------------------------------------------
      41              : 
      42              : static const ElementStyle markerStyle {
      43              :     { Sid::repeatLeftPlacement, Pid::PLACEMENT },
      44              :     { Sid::repeatMinDistance,   Pid::MIN_DISTANCE },
      45              : };
      46              : 
      47              : //---------------------------------------------------------
      48              : //   MarkerTypeTable
      49              : //---------------------------------------------------------
      50              : 
      51              : const std::vector<MarkerTypeTableItem> markerTypeTable {
      52              :     { MarkerType::SEGNO,      "<sym>segno</sym>",               "segno", false },
      53              :     { MarkerType::VARSEGNO,   "<sym>segnoSerpent1</sym>",       "varsegno", false },
      54              :     { MarkerType::CODA,       "<sym>coda</sym>",                "codab", false },
      55              :     { MarkerType::VARCODA,    "<sym>codaSquare</sym>",          "varcoda", false },
      56              :     { MarkerType::CODETTA,    "<sym>coda</sym><sym>coda</sym>", "codetta", false },
      57              :     { MarkerType::FINE,       "Fine",                           "fine", true },
      58              :     { MarkerType::TOCODA,     "To Coda",                        "coda", true },
      59              :     { MarkerType::TOCODASYM,  "To <sym>coda</sym>",             "coda", true },
      60              :     { MarkerType::DA_CODA,    "Da Coda",                        "coda", true },
      61              :     { MarkerType::DA_DBLCODA, "Da Doppia Coda",                 "coda", true },
      62              : };
      63              : 
      64              : //---------------------------------------------------------
      65              : //   Marker
      66              : //---------------------------------------------------------
      67              : 
      68          220 : Marker::Marker(DummyParentOr<EngravingItem> parent)
      69          220 :     : Marker(parent, TextStyleType::REPEAT_LEFT)
      70              : {
      71          220 :     resetProperty(Pid::MUSIC_SYMBOL_SIZE);
      72          220 : }
      73              : 
      74          230 : Marker::Marker(DummyParentOr<EngravingItem> parent, TextStyleType tid)
      75          230 :     : TextBase(ElementType::MARKER, parent, tid, ElementFlag::MOVABLE | ElementFlag::ON_STAFF | ElementFlag::SYSTEM)
      76              : {
      77          230 :     initElementStyle(&markerStyle);
      78          230 :     resetProperty(Pid::MUSIC_SYMBOL_SIZE);
      79          230 :     m_markerType = MarkerType::FINE;
      80          230 : }
      81              : 
      82              : //---------------------------------------------------------
      83              : //   setMarkerType
      84              : //---------------------------------------------------------
      85              : 
      86          234 : void Marker::setMarkerType(MarkerType t)
      87              : {
      88          234 :     bool changeLabel = getProperty(Pid::LABEL) == propertyDefault(Pid::LABEL);
      89          234 :     m_markerType = t;
      90          987 :     for (const MarkerTypeTableItem& p : markerTypeTable) {
      91          972 :         if (p.type == t) {
      92          219 :             if (empty()) {
      93           69 :                 setXmlText(String::fromAscii(p.text.ascii()));
      94              :             }
      95          219 :             if (changeLabel) {
      96           79 :                 setLabel(String::fromAscii(p.label.ascii()));
      97              :             }
      98          219 :             TextStyleType ts = p.rightAligned ? TextStyleType::REPEAT_RIGHT : TextStyleType::REPEAT_LEFT;
      99          219 :             if (textStyleType() != ts) {
     100           17 :                 initTextStyleType(ts);
     101              :             }
     102              : 
     103          219 :             break;
     104              :         }
     105              :     }
     106          234 : }
     107              : 
     108              : //---------------------------------------------------------
     109              : //   markerTypeUserName
     110              : //---------------------------------------------------------
     111              : 
     112            0 : String Marker::markerTypeUserName() const
     113              : {
     114            0 :     return TConv::translatedUserName(m_markerType);
     115              : }
     116              : 
     117              : //---------------------------------------------------------
     118              : //   getProperty
     119              : //---------------------------------------------------------
     120              : 
     121         2286 : PropertyValue Marker::getProperty(Pid propertyId) const
     122              : {
     123         2286 :     switch (propertyId) {
     124          234 :     case Pid::LABEL:
     125          234 :         return label();
     126           75 :     case Pid::MARKER_TYPE:
     127           75 :         return markerType();
     128           75 :     case Pid::MARKER_CENTER_ON_SYMBOL:
     129           75 :         return centerOnSymbol();
     130         1902 :     default:
     131         1902 :         break;
     132              :     }
     133         1902 :     return TextBase::getProperty(propertyId);
     134              : }
     135              : 
     136              : //---------------------------------------------------------
     137              : //   setProperty
     138              : //---------------------------------------------------------
     139              : 
     140         7830 : bool Marker::setProperty(Pid propertyId, const PropertyValue& v)
     141              : {
     142         7830 :     switch (propertyId) {
     143           31 :     case Pid::LABEL:
     144           31 :         setLabel(v.value<String>());
     145           31 :         break;
     146           40 :     case Pid::MARKER_TYPE:
     147           40 :         setMarkerType(v.value<MarkerType>());
     148           40 :         break;
     149            0 :     case Pid::MARKER_CENTER_ON_SYMBOL:
     150            0 :         setCenterOnSymbol(v.toBool());
     151            0 :         break;
     152         7759 :     default:
     153         7759 :         if (!TextBase::setProperty(propertyId, v)) {
     154            0 :             return false;
     155              :         }
     156         7759 :         break;
     157              :     }
     158         7830 :     triggerLayout();
     159         7830 :     return true;
     160              : }
     161              : 
     162              : //---------------------------------------------------------
     163              : //   propertyDefault
     164              : //---------------------------------------------------------
     165              : 
     166         1787 : PropertyValue Marker::propertyDefault(Pid propertyId) const
     167              : {
     168         1787 :     switch (propertyId) {
     169          291 :     case Pid::LABEL:
     170         1619 :         for (const MarkerTypeTableItem& p : markerTypeTable) {
     171         1619 :             if (m_markerType == p.type) {
     172          291 :                 return String::fromAscii(p.label.ascii());
     173              :             }
     174              :         }
     175            0 :         return String();
     176           75 :     case Pid::MARKER_TYPE:
     177          150 :         return MarkerType::FINE;
     178            2 :     case Pid::PLACEMENT:
     179            2 :         return PlacementV::ABOVE;
     180           75 :     case Pid::MARKER_CENTER_ON_SYMBOL:
     181           75 :         return true;
     182          450 :     case Pid::MUSIC_SYMBOL_SIZE:
     183          450 :         return 18.0;
     184          894 :     default:
     185          894 :         break;
     186              :     }
     187          894 :     return TextBase::propertyDefault(propertyId);
     188              : }
     189              : 
     190              : //---------------------------------------------------------
     191              : //   nextSegmentElement
     192              : //---------------------------------------------------------
     193              : 
     194            0 : EngravingItem* Marker::nextSegmentElement()
     195              : {
     196              :     Segment* seg;
     197            0 :     if (markerType() == MarkerType::FINE) {
     198            0 :         seg = measure()->last();
     199            0 :         return seg->firstElementForNavigation(staffIdx());
     200              :     }
     201            0 :     Measure* prevMeasure = measure()->prevMeasureMM();
     202            0 :     if (prevMeasure) {
     203            0 :         seg = prevMeasure->last();
     204            0 :         return seg->firstElementForNavigation(staffIdx());
     205              :     }
     206            0 :     return EngravingItem::nextSegmentElement();
     207              : }
     208              : 
     209              : //---------------------------------------------------------
     210              : //   prevSegmentElement
     211              : //---------------------------------------------------------
     212              : 
     213            0 : EngravingItem* Marker::prevSegmentElement()
     214              : {
     215              :     //it's the same barline
     216            0 :     return nextSegmentElement();
     217              : }
     218              : 
     219              : //---------------------------------------------------------
     220              : //   accessibleInfo
     221              : //---------------------------------------------------------
     222              : 
     223            0 : String Marker::accessibleInfo() const
     224              : {
     225            0 :     return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), markerTypeUserName());
     226              : }
     227              : 
     228            0 : std::vector<LineF> Marker::dragAnchorLines() const
     229              : {
     230            0 :     Measure* m = measure();
     231              : 
     232            0 :     std::vector<LineF> lines(TextBase::dragAnchorLines());
     233              : 
     234            0 :     if (!m || !isRightMarker()) {
     235            0 :         return lines;
     236              :     }
     237              : 
     238            0 :     for (LineF& l : lines) {
     239            0 :         l.setP1(l.p1() + PointF(m->width(), 0.0));
     240              :     }
     241              : 
     242            0 :     return lines;
     243            0 : }
     244              : 
     245          652 : String Marker::symbolString() const
     246              : {
     247              :     // Returns the coda/segno symbol if present
     248              :     const static std::array REPEAT_SYMBOL_NAMES {
     249              :         String(u"<sym>coda</sym>"),
     250              :         String(u"<sym>codaSquare</sym>"),
     251              :         String(u"<sym>codaJapanes</sym>"),
     252              :         String(u"<sym>segno</sym>"),
     253              :         String(u"<sym>segnoSerpent1</sym>"),
     254              :         String(u"<sym>segnoSerpent2</sym>"),
     255              :         String(u"<sym>segnoJapanese</sym>"),
     256          652 :     };
     257              : 
     258         2600 :     for (const String& sym : REPEAT_SYMBOL_NAMES) {
     259         2408 :         if (xmlText().contains(sym)) {
     260          460 :             return sym;
     261              :         }
     262              :     }
     263              : 
     264          192 :     return String();
     265              : }
     266              : 
     267              : //---------------------------------------------------------
     268              : //   subtypeUserName
     269              : //---------------------------------------------------------
     270              : 
     271            0 : muse::TranslatableString Marker::subtypeUserName() const
     272              : {
     273            0 :     return TConv::userName(m_markerType);
     274              : }
     275              : }
        

Generated by: LCOV version 2.0-1