LCOV - code coverage report
Current view: top level - src/engraving/dom - durationelement.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 98.3 % 60 59
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 "durationelement.h"
      24              : 
      25              : #include "property.h"
      26              : #include "score.h"
      27              : #include "staff.h"
      28              : #include "tuplet.h"
      29              : 
      30              : #include "editing/transaction/undostack.h"
      31              : 
      32              : using namespace mu;
      33              : using namespace mu::engraving;
      34              : 
      35              : namespace mu::engraving {
      36              : //---------------------------------------------------------
      37              : //   DurationElement
      38              : //---------------------------------------------------------
      39              : 
      40        53137 : DurationElement::DurationElement(const ElementType& type, EngravingObject* parent, ElementFlags f)
      41        53137 :     : EngravingItem(type, parent, f)
      42              : {
      43        53137 :     m_tuplet = 0;
      44        53137 : }
      45              : 
      46              : //---------------------------------------------------------
      47              : //   DurationElement
      48              : //---------------------------------------------------------
      49              : 
      50         5081 : DurationElement::DurationElement(const DurationElement& e, bool link)
      51         5081 :     : EngravingItem(e, link)
      52              : {
      53         5081 :     m_tuplet   = 0;      // e._tuplet;
      54         5081 :     m_duration = e.m_duration;
      55         5081 : }
      56              : 
      57              : //---------------------------------------------------------
      58              : //   ~DurationElement
      59              : //---------------------------------------------------------
      60              : 
      61        51675 : DurationElement::~DurationElement()
      62              : {
      63        51675 :     if (m_tuplet) {
      64         2379 :         setTuplet(nullptr);
      65              :     }
      66        51675 : }
      67              : 
      68              : //---------------------------------------------------------
      69              : //   topTuplet
      70              : //---------------------------------------------------------
      71              : 
      72       121033 : Tuplet* DurationElement::topTuplet() const
      73              : {
      74       121033 :     Tuplet* t = tuplet();
      75       121033 :     if (t) {
      76         9075 :         while (t->tuplet()) {
      77         1888 :             t = t->tuplet();
      78              :         }
      79              :     }
      80       121033 :     return t;
      81              : }
      82              : 
      83              : //---------------------------------------------------------
      84              : //   globalTicks
      85              : //---------------------------------------------------------
      86              : 
      87      1500004 : Fraction DurationElement::globalTicks() const
      88              : {
      89      1500004 :     Fraction f(m_duration);
      90      1698624 :     for (Tuplet* t = tuplet(); t; t = t->tuplet()) {
      91       198620 :         f /= t->ratio();
      92              :     }
      93      1500004 :     return f;
      94              : }
      95              : 
      96           28 : float DurationElement::timeStretchFactor() const
      97              : {
      98           28 :     int nominalDuration = m_duration.ticks();
      99           28 :     int actualDuration = actualTicks().ticks();
     100              : 
     101           28 :     return actualDuration / static_cast<float>(nominalDuration);
     102              : }
     103              : 
     104              : //---------------------------------------------------------
     105              : //   actualTicks
     106              : //---------------------------------------------------------
     107              : 
     108      1447997 : Fraction DurationElement::actualTicksAt(const Fraction& tick) const
     109              : {
     110              :     // Use when tick() is unreliable, for example when pasting
     111      1447997 :     return globalTicks() / staff()->timeStretch(tick);
     112              : }
     113              : 
     114      1445786 : Fraction DurationElement::actualTicks() const
     115              : {
     116      1445786 :     return actualTicksAt(tick());
     117              : }
     118              : 
     119              : //---------------------------------------------------------
     120              : //   readAddTuplet
     121              : //---------------------------------------------------------
     122              : 
     123          142 : void DurationElement::readAddTuplet(Tuplet* t)
     124              : {
     125          142 :     setTuplet(t);
     126          142 :     if (!score()->undoStack()->hasActiveTransaction()) { // HACK, also added in Undo::AddElement()
     127            0 :         t->add(this);
     128              :     }
     129          142 : }
     130              : 
     131        10196 : void DurationElement::setTuplet(Tuplet* t)
     132              : {
     133        10196 :     if (m_tuplet) {
     134         4115 :         m_tuplet->removeDurationElement(this);
     135              :     }
     136              : 
     137        10196 :     m_tuplet = t;
     138              : 
     139        10196 :     if (m_tuplet) {
     140         5657 :         m_tuplet->addDurationElement(this);
     141              :     }
     142        10196 : }
     143              : 
     144              : //---------------------------------------------------------
     145              : //   getProperty
     146              : //---------------------------------------------------------
     147              : 
     148       345903 : PropertyValue DurationElement::getProperty(Pid propertyId) const
     149              : {
     150       345903 :     switch (propertyId) {
     151          522 :     case Pid::DURATION:
     152          522 :         return PropertyValue::fromValue(m_duration);
     153       345381 :     default:
     154       345381 :         return EngravingItem::getProperty(propertyId);
     155              :     }
     156              : }
     157              : 
     158              : //---------------------------------------------------------
     159              : //   setProperty
     160              : //---------------------------------------------------------
     161              : 
     162         8185 : bool DurationElement::setProperty(Pid propertyId, const PropertyValue& v)
     163              : {
     164         8185 :     switch (propertyId) {
     165          198 :     case Pid::DURATION: {
     166          198 :         Fraction f(v.value<Fraction>());
     167          198 :         setTicks(f);
     168          198 :         triggerLayout();
     169              :     }
     170          198 :     break;
     171         7987 :     default:
     172         7987 :         return EngravingItem::setProperty(propertyId, v);
     173              :     }
     174          198 :     return true;
     175              : }
     176              : }
        

Generated by: LCOV version 2.0-1