LCOV - code coverage report
Current view: top level - src/engraving/dom - tempotext.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 38.7 % 217 84
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 <algorithm>
      24              : #include <cmath>
      25              : 
      26              : #include <unordered_map>
      27              : 
      28              : #include "containers.h"
      29              : #include "translation.h"
      30              : 
      31              : #include "types/typesconv.h"
      32              : #include "types/constants.h"
      33              : 
      34              : #include "score.h"
      35              : #include "segment.h"
      36              : #include "tempotext.h"
      37              : 
      38              : #include "log.h"
      39              : 
      40              : using namespace mu;
      41              : using namespace mu::engraving;
      42              : 
      43              : namespace mu::engraving {
      44              : //TODO: textChanged() needs to be called during/after editing
      45              : 
      46              : //---------------------------------------------------------
      47              : //   tempoStyle
      48              : //---------------------------------------------------------
      49              : 
      50              : static const ElementStyle tempoStyle {
      51              :     { Sid::tempoSystemFlag,                    Pid::SYSTEM_FLAG },
      52              :     { Sid::tempoPlacement,                     Pid::PLACEMENT },
      53              :     { Sid::tempoMinDistance,                   Pid::MIN_DISTANCE },
      54              : };
      55              : 
      56              : //---------------------------------------------------------
      57              : //   TempoText
      58              : //---------------------------------------------------------
      59              : 
      60          811 : TempoText::TempoText(DummyParentOr<Segment> parent)
      61          811 :     : TextBase(ElementType::TEMPO_TEXT, parent, TextStyleType::TEMPO, ElementFlag::SYSTEM | ElementFlag::ON_STAFF)
      62              : {
      63          811 :     initElementStyle(&tempoStyle);
      64          811 :     m_tempoTextType  = TempoTextType::NORMAL;
      65          811 :     m_tempo          = 2.0;        // propertyDefault(P_TEMPO).toDouble();
      66          811 :     m_followText     = false;
      67          811 :     m_relative       = 1.0;
      68          811 :     m_isRelative     = false;
      69              : 
      70          811 :     resetProperty(Pid::MUSIC_SYMBOL_SIZE);
      71          811 : }
      72              : 
      73            2 : void TempoText::setTempoTextType(TempoTextType ttt)
      74              : {
      75            2 :     m_tempoTextType = ttt;
      76            2 : }
      77              : 
      78            8 : double TempoText::tempoBpm() const
      79              : {
      80              :     //! NOTE: find tempo in format " = 180"
      81            8 :     std::regex regex("\\s*=\\s*(\\d+[.]{0,1}\\d*)");
      82            8 :     std::smatch match;
      83            8 :     std::string stru8 = xmlText().toStdString();
      84            8 :     std::regex_search(stru8, match, regex);
      85            8 :     if (match.empty() || match.size() < 1) {
      86            0 :         return 0;
      87              :     }
      88              : 
      89            8 :     double tempo = String::fromStdString(match[1].str()).toDouble();
      90            8 :     return tempo;
      91            8 : }
      92              : 
      93              : //---------------------------------------------------------
      94              : //   TempoPattern
      95              : //---------------------------------------------------------
      96              : 
      97              : struct TempoPattern {
      98              :     const char* pattern;
      99              :     double f;
     100              :     TDuration d;
     101          836 :     TempoPattern(const char* s, double v, DurationType val, int dots = 0)
     102          836 :         : pattern(s), f(v), d(val)
     103              :     {
     104          836 :         d.setDots(dots);
     105          836 :     }
     106              : };
     107              : 
     108              : // note: findTempoDuration requires the longer patterns to be before the shorter patterns in tp
     109              : 
     110              : static const TempoPattern tp[] = {
     111              :     TempoPattern("\uECA5\\s*\uECB7\\s*\uECB7", 1.75 / 60.0,  DurationType::V_QUARTER, 2), // double dotted 1/4
     112              :     TempoPattern("\uECA5\\s*\uECB7",           1.5 / 60.0,   DurationType::V_QUARTER, 1), // dotted 1/4
     113              :     TempoPattern("\uECA5",                     1.0 / 60.0,   DurationType::V_QUARTER),    // 1/4
     114              :     TempoPattern("\uECA3\\s*\uECB7\\s*\uECB7", 1.75 / 30.0,  DurationType::V_HALF, 2),    // double dotted 1/2
     115              :     TempoPattern("\uECA3\\s*\uECB7",           1.5 / 30.0,   DurationType::V_HALF, 1),    // dotted 1/2
     116              :     TempoPattern("\uECA3",                     1.0 / 30.0,   DurationType::V_HALF),       // 1/2
     117              :     TempoPattern("\uECA7\\s*\uECB7\\s*\uECB7", 1.75 / 120.0, DurationType::V_EIGHTH, 2),  // double dotted 1/8
     118              :     TempoPattern("\uECA7\\s*\uECB7",           1.5 / 120.0,  DurationType::V_EIGHTH, 1),  // dotted 1/8
     119              :     TempoPattern("\uECA7",                     1.0 / 120.0,  DurationType::V_EIGHTH),     // 1/8
     120              :     TempoPattern("\uECA2\\s*\uECB7",           1.5 / 15.0,   DurationType::V_WHOLE, 1),   // dotted whole
     121              :     TempoPattern("\uECA2",                     1.0 / 15.0,   DurationType::V_WHOLE),      // whole
     122              :     TempoPattern("\uECA9\\s*\uECB7",           1.5 / 240.0,  DurationType::V_16TH, 1),    // dotted 1/16
     123              :     TempoPattern("\uECA9",                     1.0 / 240.0,  DurationType::V_16TH),       // 1/16
     124              :     TempoPattern("\uECAB\\s*\uECB7",           1.5 / 480.0,  DurationType::V_32ND, 1),    // dotted 1/32
     125              :     TempoPattern("\uECAB",                     1.0 / 480.0,  DurationType::V_32ND),       // 1/32
     126              :     TempoPattern("\uECA1",                     1.0 / 7.5,    DurationType::V_BREVE),      // longa
     127              :     TempoPattern("\uECA0",                     1.0 / 7.5,    DurationType::V_BREVE),      // double whole
     128              :     TempoPattern("\uECAD",                     1.0 / 960.0,  DurationType::V_64TH),       // 1/64
     129              :     TempoPattern("\uECAF",                     1.0 / 1920.0, DurationType::V_128TH),      // 1/128
     130              :     TempoPattern("\uECB1",                     1.0 / 3840.0, DurationType::V_256TH),      // 1/256
     131              :     TempoPattern("\uECB3",                     1.0 / 7680.0, DurationType::V_512TH),      // 1/512
     132              :     TempoPattern("\uECB5",                     1.0 / 15360.0, DurationType::V_1024TH),     // 1/1024
     133              : };
     134              : 
     135              : //---------------------------------------------------------
     136              : //   findTempoDuration
     137              : //    find the duration part (note + dot) of a tempo text in string s
     138              : //    return the match position or -1 if not found
     139              : //    set len to the match length and dur to the duration value
     140              : //---------------------------------------------------------
     141              : 
     142          625 : int TempoText::findTempoDuration(const String& s, int& len, TDuration& dur)
     143              : {
     144          625 :     len = 0;
     145          625 :     dur = TDuration();
     146          625 :     std::string su8 = s.toStdString();
     147        10235 :     for (const auto& i : tp) {
     148         9832 :         std::regex regex(i.pattern);
     149         9832 :         std::smatch match;
     150         9832 :         std::regex_search(su8, match, regex);
     151         9832 :         if (!match.empty()) {
     152          222 :             len = static_cast<int>(String::fromStdString(match[0].str()).size());
     153          222 :             dur = i.d;
     154          444 :             return std::distance(su8.cbegin(), match[0].first);
     155              :         }
     156        10054 :     }
     157          403 :     return -1;
     158          625 : }
     159              : 
     160            8 : TDuration TempoText::duration() const
     161              : {
     162            8 :     int dummy = 0;
     163            8 :     TDuration result;
     164              : 
     165            8 :     findTempoDuration(plainText(), dummy, result);
     166              : 
     167            8 :     return result;
     168              : }
     169              : 
     170              : static const TempoPattern tpSym[] = {
     171              :     TempoPattern("<sym>metNoteQuarterUp</sym><sym>space</sym><sym>metAugmentationDot</sym><sym>metAugmentationDot</sym>",
     172              :                  1.75 / 60.0, DurationType::V_QUARTER, 2),                                                                                                                          // double dotted 1/4
     173              :     TempoPattern("<sym>metNoteQuarterUp</sym><sym>space</sym><sym>metAugmentationDot</sym>",          1.5 / 60.0,  DurationType::V_QUARTER,
     174              :                  1),                                                                                                                           // dotted 1/4
     175              :     TempoPattern("<sym>metNoteQuarterUp</sym>",                                           1.0 / 60.0,  DurationType::V_QUARTER),  // 1/4
     176              :     TempoPattern("<sym>metNoteHalfUp</sym><sym>space</sym><sym>metAugmentationDot</sym><sym>metAugmentationDot</sym>",
     177              :                  1.75 / 30.0, DurationType::V_HALF, 2),                                                                                                                       // double dotted 1/2
     178              :     TempoPattern("<sym>metNoteHalfUp</sym><sym>space</sym><sym>metAugmentationDot</sym>",             1.5 / 30.0,  DurationType::V_HALF, 1),    // dotted 1/2
     179              :     TempoPattern("<sym>metNoteHalfUp</sym>",                                              1.0 / 30.0,  DurationType::V_HALF),     // 1/2
     180              :     TempoPattern("<sym>metNote8thUp</sym><sym>space</sym><sym>metAugmentationDot</sym><sym>metAugmentationDot</sym>",         1.75 / 120.0,
     181              :                  DurationType::V_EIGHTH, 2),                                                                                                                    // double dotted 1/8
     182              :     TempoPattern("<sym>metNote8thUp</sym><sym>space</sym><sym>metAugmentationDot</sym>",              1.5 / 120.0, DurationType::V_EIGHTH,
     183              :                  1),                                                                                                                           // dotted 1/8
     184              :     TempoPattern("<sym>metNote8thUp</sym>",                                               1.0 / 120.0, DurationType::V_EIGHTH),   // 1/8
     185              :     TempoPattern("<sym>metNoteWhole</sym><sym>space</sym><sym>metAugmentationDot</sym>",              1.5 / 15.0,  DurationType::V_WHOLE,
     186              :                  1),                                                                                                                             // dotted whole
     187              :     TempoPattern("<sym>metNoteWhole</sym>",                                               1.0 / 15.0,  DurationType::V_WHOLE),    // whole
     188              :     TempoPattern("<sym>metNote16thUp</sym><sym>space</sym><sym>metAugmentationDot</sym>",             1.5 / 240.0, DurationType::V_16TH, 1),  // dotted 1/16
     189              :     TempoPattern("<sym>metNote16thUp</sym>",                                              1.0 / 240.0, DurationType::V_16TH),     // 1/16
     190              :     TempoPattern("<sym>metNote32ndUp</sym><sym>space</sym><sym>metAugmentationDot</sym>",             1.5 / 480.0, DurationType::V_32ND, 1),  // dotted 1/32
     191              :     TempoPattern("<sym>metNote32ndUp</sym>",                                              1.0 / 480.0, DurationType::V_32ND),     // 1/32
     192              :     TempoPattern("<sym>metNoteDoubleWholeSquare</sym>",                                   1.0 / 7.5,   DurationType::V_BREVE),    // longa
     193              :     TempoPattern("<sym>metNoteDoubleWhole</sym>",                                         1.0 / 7.5,   DurationType::V_BREVE),    // double whole
     194              :     TempoPattern("<sym>metNote64thUp</sym>",                                              1.0 / 960.0, DurationType::V_64TH),     // 1/64
     195              :     TempoPattern("<sym>metNote128thUp</sym>",                                             1.0 / 1920.0, DurationType::V_128TH),    // 1/128
     196              :     TempoPattern("<sym>metNote256thUp</sym>",                                             1.0 / 3840.0, DurationType::V_256TH),    // 1/256
     197              :     TempoPattern("<sym>metNote512thUp</sym>",                                             1.0 / 7680.0, DurationType::V_512TH),    // 1/512
     198              :     TempoPattern("<sym>metNote1024thUp</sym>",                                            1.0 / 15360.0, DurationType::V_1024TH),  // 1/1024
     199              : };
     200              : 
     201              : //---------------------------------------------------------
     202              : //   duration2tempoTextString
     203              : //    find the tempoText string representation for duration
     204              : //---------------------------------------------------------
     205              : 
     206          163 : String TempoText::duration2tempoTextString(const TDuration dur)
     207              : {
     208          651 :     for (const TempoPattern& pa : tpSym) {
     209          651 :         if (pa.d == dur) {
     210          163 :             String res = String::fromUtf8(pa.pattern);
     211          163 :             return res;
     212            0 :         }
     213              :     }
     214            0 :     return u"";
     215              : }
     216              : 
     217              : //---------------------------------------------------------
     218              : // tempo
     219              : //---------------------------------------------------------
     220              : 
     221          777 : BeatsPerSecond TempoText::tempo() const
     222              : {
     223          777 :     if (m_isRelative) {
     224            0 :         const BeatsPerSecond tempoBefore = score()->tempo(tick() - Fraction::eps());
     225            0 :         const BeatsPerSecond v = tempoBefore * m_relative;
     226            0 :         return BeatsPerSecond(std::clamp(v.val, Constants::MIN_TEMPO.val, Constants::MAX_TEMPO.val));
     227              :     }
     228          777 :     return m_tempo;
     229              : }
     230              : 
     231              : //---------------------------------------------------------
     232              : //   undoChangeProperty
     233              : //---------------------------------------------------------
     234              : 
     235            0 : void TempoText::undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps)
     236              : {
     237            0 :     if (id == Pid::TEMPO_FOLLOW_TEXT) {
     238            0 :         EngravingObject::undoChangeProperty(id, v, ps);
     239            0 :         if (m_followText) {
     240            0 :             updateTempo();
     241              :         }
     242              :     } else {
     243            0 :         EngravingObject::undoChangeProperty(id, v, ps);
     244              :     }
     245            0 : }
     246              : 
     247              : //---------------------------------------------------------
     248              : //   updateTempo
     249              : //---------------------------------------------------------
     250              : 
     251            0 : void TempoText::updateTempo()
     252              : {
     253              :     // cache regexp, they are costly to create
     254            0 :     static std::unordered_map<String, std::regex> regexps;
     255            0 :     static std::unordered_map<String, std::regex> regexps2;
     256            0 :     String s = plainText();
     257            0 :     s.replace(u",", u".");
     258            0 :     s.replace(u"<sym>space</sym>", u" ");
     259            0 :     s.replace(u"≒", u"=");
     260            0 :     s.replace(u"≈", u"=");
     261            0 :     s.replace(u"~", u"=");
     262            0 :     s.replace(u"ca.", u"");
     263            0 :     s.replace(u"c.", u"");
     264            0 :     s.replace(u"approx.", u"");
     265            0 :     std::string su8 = s.toStdString();
     266            0 :     for (const TempoPattern& pa : tp) {
     267            0 :         String pattern = String::fromUtf8(pa.pattern);
     268            0 :         std::regex re;
     269            0 :         if (!muse::contains(regexps, String::fromUtf8(pa.pattern))) {
     270            0 :             re = std::regex(String(u"%1\\s*=\\s*(\\d+[.]{0,1}\\d*)\\s*").arg(pattern).toStdString());
     271            0 :             regexps[pattern] = re;
     272              :         }
     273            0 :         re = muse::value(regexps, pattern);
     274            0 :         std::smatch match;
     275            0 :         std::regex_search(su8, match, re);
     276            0 :         if (!match.empty()) {
     277            0 :             if (match.size() == 2) {
     278            0 :                 BeatsPerSecond nt = BeatsPerSecond(String::fromStdString(match[1].str()).toDouble() * pa.f);
     279            0 :                 if (m_isRelative || nt != m_tempo) {
     280            0 :                     undoChangeProperty(Pid::TEMPO, PropertyValue(nt), propertyFlags(Pid::TEMPO));
     281            0 :                     m_relative = 1.0;
     282            0 :                     m_isRelative = false;
     283              :                 }
     284            0 :                 break;
     285              :             }
     286              :         } else {
     287            0 :             for (const TempoPattern& pa2 : tp) {
     288            0 :                 String pattern2 = String::fromUtf8(pa2.pattern);
     289            0 :                 String key = String(u"%1_%2").arg(pattern, pattern2);
     290            0 :                 std::regex re2;
     291            0 :                 if (!muse::contains(regexps2, key)) {
     292            0 :                     re2 = std::regex(String(u"%1\\s*=\\s*%2\\s*").arg(pattern, pattern2).toStdString());
     293            0 :                     regexps2[key] = re2;
     294              :                 }
     295            0 :                 re2 = muse::value(regexps2, key);
     296            0 :                 std::smatch match2;
     297            0 :                 std::regex_search(su8, match2, re2);
     298            0 :                 if (!match2.empty()) {
     299            0 :                     m_relative = pa2.f / pa.f;
     300            0 :                     m_isRelative = true;
     301            0 :                     return;
     302              :                 }
     303            0 :             }
     304              :         }
     305            0 :     }
     306            0 : }
     307              : 
     308              : //---------------------------------------------------------
     309              : //   setTempo
     310              : //---------------------------------------------------------
     311              : 
     312          799 : void TempoText::setTempo(BeatsPerSecond v)
     313              : {
     314          799 :     if (v.val < Constants::MIN_TEMPO.val) {
     315            0 :         v = Constants::MIN_TEMPO;
     316          799 :     } else if (v.val > Constants::MAX_TEMPO.val) {
     317            0 :         v = Constants::MAX_TEMPO;
     318              :     }
     319          799 :     m_tempo = v;
     320          799 :     m_relative = 1.0;
     321          799 :     m_isRelative = false;
     322          799 : }
     323              : 
     324              : //---------------------------------------------------------
     325              : //   getProperty
     326              : //---------------------------------------------------------
     327              : 
     328         8291 : PropertyValue TempoText::getProperty(Pid propertyId) const
     329              : {
     330         8291 :     switch (propertyId) {
     331          565 :     case Pid::PLAY:
     332          565 :         return m_playTempoText;
     333            0 :     case Pid::TEMPO:
     334            0 :         return m_tempo;
     335            0 :     case Pid::TEMPO_FOLLOW_TEXT:
     336            0 :         return m_followText;
     337           10 :     case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
     338           10 :         return m_alignRightOfRehearsalMark;
     339         7716 :     default:
     340         7716 :         return TextBase::getProperty(propertyId);
     341              :     }
     342              : }
     343              : 
     344              : //---------------------------------------------------------
     345              : //   setProperty
     346              : //---------------------------------------------------------
     347              : 
     348        16862 : bool TempoText::setProperty(Pid propertyId, const PropertyValue& v)
     349              : {
     350        16862 :     switch (propertyId) {
     351            0 :     case Pid::PLAY:
     352            0 :         setPlayTempoText(v.toBool());
     353            0 :         break;
     354            0 :     case Pid::TEMPO:
     355            0 :         setTempo(v.value<BeatsPerSecond>());
     356            0 :         break;
     357            0 :     case Pid::TEMPO_FOLLOW_TEXT:
     358            0 :         setFollowText(v.toBool());
     359            0 :         break;
     360            0 :     case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
     361            0 :         m_alignRightOfRehearsalMark = v.toBool();
     362            0 :         break;
     363        16862 :     default:
     364        16862 :         if (!TextBase::setProperty(propertyId, v)) {
     365            0 :             return false;
     366              :         }
     367        16862 :         break;
     368              :     }
     369        16862 :     triggerLayout();
     370        16862 :     return true;
     371              : }
     372              : 
     373              : //---------------------------------------------------------
     374              : //   propertyDefault
     375              : //---------------------------------------------------------
     376              : 
     377         7519 : PropertyValue TempoText::propertyDefault(Pid id) const
     378              : {
     379         7519 :     switch (id) {
     380          565 :     case Pid::PLAY:
     381          565 :         return true;
     382          565 :     case Pid::TEXT_STYLE:
     383          565 :         return TextStyleType::TEMPO;
     384            0 :     case Pid::TEMPO:
     385            0 :         return BeatsPerSecond(2.0);
     386            0 :     case Pid::TEMPO_FOLLOW_TEXT:
     387            0 :         return false;
     388            0 :     case Pid::TEMPO_ALIGN_RIGHT_OF_REHEARSAL_MARK:
     389            0 :         return true;
     390         6389 :     default:
     391         6389 :         return TextBase::propertyDefault(id);
     392              :     }
     393              : }
     394              : 
     395              : //---------------------------------------------------------
     396              : //   duration2userName
     397              : //---------------------------------------------------------
     398              : 
     399            0 : String TempoText::duration2userName(const TDuration t)
     400              : {
     401            0 :     String dots;
     402            0 :     switch (t.dots()) {
     403            0 :     case 1: dots = muse::mtrc("engraving", "Dotted %1").arg(TConv::translatedUserName(t.type()));
     404            0 :         break;
     405            0 :     case 2: dots = muse::mtrc("engraving", "Double dotted %1").arg(TConv::translatedUserName(t.type()));
     406            0 :         break;
     407            0 :     case 3: dots = muse::mtrc("engraving", "Triple dotted %1").arg(TConv::translatedUserName(t.type()));
     408            0 :         break;
     409            0 :     case 4: dots = muse::mtrc("engraving", "Quadruple dotted %1").arg(TConv::translatedUserName(t.type()));
     410            0 :         break;
     411            0 :     default:
     412            0 :         dots = TConv::translatedUserName(t.type());
     413            0 :         break;
     414              :     }
     415            0 :     return dots;
     416            0 : }
     417              : 
     418              : //---------------------------------------------------------
     419              : //   accessibleInfo
     420              : //---------------------------------------------------------
     421              : 
     422            0 : String TempoText::accessibleInfo() const
     423              : {
     424            0 :     String info = tempoInfo();
     425            0 :     if (info.empty()) {
     426            0 :         return TextBase::accessibleInfo();
     427              :     }
     428              : 
     429            0 :     return String(u"%1: %2").arg(EngravingItem::accessibleInfo(), info);
     430            0 : }
     431              : 
     432            0 : String TempoText::tempoInfo() const
     433              : {
     434            0 :     TDuration t1;
     435            0 :     TDuration t2;
     436              :     int len1;
     437              :     int len2;
     438            0 :     String text = plainText();
     439            0 :     String firstPart = text.split(u" = ").front();
     440            0 :     String secondPart = text.split(u" = ").back();
     441            0 :     int x1 = findTempoDuration(firstPart, len1, t1);
     442            0 :     int x2 = -1;
     443            0 :     if (m_relative) {
     444            0 :         x2 = findTempoDuration(secondPart, len2, t2);
     445              :     }
     446              : 
     447            0 :     String info;
     448              : 
     449            0 :     if (x1 != -1) {
     450            0 :         String dots1 = duration2userName(t1);
     451            0 :         if (x2 != -1) {
     452            0 :             String dots2 = duration2userName(t2);
     453              :             //: %1 and %2 are note durations. If your language does not have different terms
     454              :             //: for "quarter note" and "quarter" (for example), or if the translations for
     455              :             //: the durations as separate strings are not suitable to be used as adjectives
     456              :             //: here, translate "%1 note" with "%1" and "%2 note" with "%2", so that just the
     457              :             //: duration will be shown.
     458            0 :             info = muse::mtrc("engraving", "%1 note = %2 note").arg(dots1, dots2);
     459            0 :         } else {
     460              :             //: %1 is a note duration. If your language does not have different terms for
     461              :             //: "quarter note" and "quarter" (for example), or if the translations for the
     462              :             //: durations as separate strings are not suitable to be used as adjectives here,
     463              :             //: translate "%1 note" with "%1", so that just the duration will be shown.
     464            0 :             info = muse::mtrc("engraving", "%1 note = %2").arg(dots1, secondPart);
     465              :         }
     466            0 :     }
     467              : 
     468            0 :     return info;
     469            0 : }
     470              : 
     471            0 : void TempoText::commitText()
     472              : {
     473            0 :     if (m_followText) {
     474            0 :         updateTempo();
     475              :     }
     476              : 
     477            0 :     TextBase::commitText();
     478            0 : }
     479              : }
        

Generated by: LCOV version 2.0-1