LCOV - code coverage report
Current view: top level - src/engraving/dom - engravingobject.cpp Coverage Total Hit
Test: filtered_coverage.info Lines: 89.5 % 361 323
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 "engravingobject.h"
      24              : 
      25              : #include <algorithm>
      26              : 
      27              : #include "global/containers.h"
      28              : 
      29              : #include "../editing/addremoveelement.h"
      30              : #include "../editing/editproperty.h"
      31              : #include "../editing/transaction/transaction.h"
      32              : #include "../editing/transaction/undostack.h"
      33              : #include "style/textstyle.h"
      34              : #include "types/typesconv.h"
      35              : 
      36              : #include "bracketitem.h"
      37              : #include "dummyparent.h"
      38              : #include "linkedobjects.h"
      39              : #include "masterscore.h"
      40              : #include "score.h"
      41              : #include "staff.h"
      42              : 
      43              : #include "log.h"
      44              : 
      45              : using namespace mu;
      46              : using namespace mu::engraving;
      47              : 
      48              : namespace mu::engraving {
      49              : ElementStyle const EngravingObject::EMPTY_STYLE;
      50              : 
      51       628829 : EngravingObject::EngravingObject(const ElementType& type, EngravingObject* parent)
      52       628829 :     : m_type(type)
      53              : {
      54       628829 :     IF_ASSERT_FAILED(this != parent) {
      55            0 :         return;
      56              :     }
      57              : 
      58       628829 :     if (type != ElementType::SCORE) {
      59       626495 :         assert(parent);
      60              :     }
      61              : 
      62              :     // The parent an object is constructed with is its parent: it is attached to it
      63              :     // right away. Passing the dummy means it is not attached to anything yet.
      64       628829 :     doSetParent(parent);
      65       628829 :     if (m_parent) {
      66       626495 :         doSetScore(m_parent->score());
      67              :     }
      68              : 
      69       628829 :     if (type == ElementType::SCORE) {
      70         2334 :         m_score = static_cast<Score*>(this);
      71              :     }
      72              : 
      73              :     // reg to debug
      74       628829 :     if (type != ElementType::SCORE) {
      75       626495 :         if (m_score && m_score->elementsProvider()) {
      76            0 :             m_score->elementsProvider()->reg(this);
      77              :         }
      78              :     }
      79            0 : }
      80              : 
      81        18740 : EngravingObject::EngravingObject(const EngravingObject& se)
      82              : {
      83        18740 :     m_type = se.m_type;
      84        18740 :     doSetParent(se.m_parent);
      85        18740 :     m_score = se.m_score;
      86        18740 :     m_elementStyle = se.m_elementStyle;
      87        18740 :     if (m_elementStyle) {
      88        18740 :         size_t n = m_elementStyle->size();
      89        18740 :         m_propertyFlagsList = new PropertyFlags[n];
      90        36394 :         for (size_t i = 0; i < n; ++i) {
      91        17654 :             m_propertyFlagsList[i] = se.m_propertyFlagsList[i];
      92              :         }
      93              :     }
      94        18740 :     m_links = 0;
      95              : 
      96              :     // reg to debug
      97        18740 :     if (m_type != ElementType::SCORE) {
      98        18740 :         if (m_score && m_score->elementsProvider()) {
      99            0 :             m_score->elementsProvider()->reg(this);
     100              :         }
     101              :     }
     102        18740 : }
     103              : 
     104              : //---------------------------------------------------------
     105              : //   ~ScoreElement
     106              : //---------------------------------------------------------
     107              : 
     108       603737 : EngravingObject::~EngravingObject()
     109              : {
     110       603737 :     if (m_parent) {
     111       601642 :         m_parent->removeChild(this);
     112              :     }
     113              : 
     114              :     {
     115       603737 :         bool isPaletteScore = score()->isPaletteScore();
     116       603737 :         bool canMoveToDummy = !this->isType(ElementType::ROOT_ITEM)
     117       599547 :                               && !this->isType(ElementType::DUMMY)
     118       597452 :                               && !this->isType(ElementType::SCORE)
     119      1203284 :                               && score()->dummy();
     120              : 
     121              :         // copy because moveToDummy might modify children
     122       603737 :         EngravingObjectList children = m_children;
     123       625098 :         for (EngravingObject* c : children) {
     124        21361 :             if (canMoveToDummy) {
     125        10754 :                 c->moveToDummy();
     126        10607 :             } else if (!isPaletteScore) {
     127        10607 :                 delete c;
     128              :             } else {
     129            0 :                 c->m_parent = nullptr;
     130              :             }
     131              :         }
     132              : 
     133       603737 :         m_children.clear();
     134       603737 :     }
     135              : 
     136       603737 :     if (score() && score()->elementsProvider()) {
     137            0 :         score()->elementsProvider()->unreg(this);
     138              :     }
     139              : 
     140       603737 :     if (m_links) {
     141        19105 :         m_links->remove(this);
     142        19105 :         if (m_links->empty()) {
     143         8625 :             delete m_links;
     144         8625 :             m_links = 0;
     145              :         }
     146              :     }
     147       603737 :     delete[] m_propertyFlagsList;
     148       603737 : }
     149              : 
     150       806174 : void EngravingObject::doSetParent(EngravingObject* p)
     151              : {
     152       806174 :     if (m_parent == p) {
     153       103263 :         return;
     154              :     }
     155              : 
     156       702911 :     IF_ASSERT_FAILED(p != this) {
     157            0 :         return;
     158              :     }
     159              : 
     160       702911 :     if (m_parent) {
     161        57676 :         m_parent->removeChild(this);
     162              :     }
     163              : 
     164       702911 :     m_parent = p;
     165              : 
     166       702911 :     if (m_parent) {
     167       702911 :         m_parent->addChild(this);
     168              :     }
     169              : }
     170              : 
     171       808827 : void EngravingObject::doSetScore(Score* sc)
     172              : {
     173       808827 :     if (m_score == sc) {
     174       177873 :         return;
     175              :     }
     176              : 
     177       630954 :     m_score = sc;
     178              : 
     179       633516 :     for (EngravingObject* ch : m_children) {
     180         2562 :         ch->doSetScore(sc);
     181              :     }
     182              : }
     183              : 
     184        11042 : void EngravingObject::moveToDummy()
     185              : {
     186        11042 :     Score* sc = score();
     187        11042 :     if (sc) {
     188        11042 :         if (sc->dummy() && sc->dummy() != this) {
     189        11042 :             setOwnershipParent(sc->dummy());
     190              :         }
     191              :     }
     192        11042 : }
     193              : 
     194          629 : static void collectChildrenItems(const EngravingObject* item, EngravingItemList& list, bool all)
     195              : {
     196         1863 :     for (EngravingObject* ch : item->children()) {
     197         1234 :         if (ch->isEngravingItem()) {
     198         1234 :             list.push_back(toEngravingItem(ch));
     199              : 
     200         1234 :             if (all) {
     201            0 :                 collectChildrenItems(ch, list, all);
     202              :             }
     203              :         }
     204              :     }
     205          629 : }
     206              : 
     207          629 : EngravingItemList EngravingObject::childrenItems(bool all) const
     208              : {
     209          629 :     EngravingItemList list;
     210          629 :     collectChildrenItems(this, list, all);
     211          629 :     return list;
     212            0 : }
     213              : 
     214         8797 : EngravingItemList EngravingObject::getChildren(bool includeInvisible) const
     215              : {
     216         8797 :     EngravingItemList childrenList;
     217        29165 :     auto collectChildren = [&](EngravingItem* item) {
     218        29165 :         if (item != this && (includeInvisible || item->visible())) {
     219        29161 :             childrenList.push_back(item);
     220              :         }
     221        37962 :     };
     222              : 
     223         8797 :     const_cast<EngravingObject*>(this)->scanElements(collectChildren);
     224              : 
     225         8797 :     return childrenList;
     226            0 : }
     227              : 
     228        21165 : void EngravingObject::setScore(Score* s)
     229              : {
     230        21165 :     doSetScore(s);
     231              : 
     232        21165 :     if (!m_parent) {
     233            0 :         return;
     234              :     }
     235              : 
     236        21165 :     if (m_parent->score() == s) {
     237        19513 :         return;
     238              :     }
     239              : 
     240         1652 :     if (m_parent->isType(ElementType::DUMMY)) {
     241           59 :         moveToDummy();
     242         1593 :     } else if (m_parent->isType(ElementType::SCORE)) {
     243            0 :         setOwnershipParent(s);
     244              :     }
     245              : }
     246              : 
     247       702911 : void EngravingObject::addChild(EngravingObject* o)
     248              : {
     249       702911 :     IF_ASSERT_FAILED(o != this) {
     250            0 :         return;
     251              :     }
     252              : 
     253       702911 :     m_children.push_back(o);
     254              : }
     255              : 
     256       659318 : void EngravingObject::removeChild(EngravingObject* o)
     257              : {
     258       659318 :     IF_ASSERT_FAILED(o->m_parent == this) {
     259            0 :         return;
     260              :     }
     261       659318 :     o->m_parent = nullptr;
     262              : 
     263              :     // Search from the back: a child is often unparented shortly after it was added, so it
     264              :     // still sits near the end of the list. That matters for the dummy, whose child list is
     265              :     // long-lived and large. Empirical evidence shows that searching from the back walks on
     266              :     // average orders-of-magnitude less list entries than searching from the front.
     267       659318 :     auto it = std::find(m_children.rbegin(), m_children.rend(), o);
     268       659318 :     if (it != m_children.rend()) {
     269      1318636 :         m_children.erase(std::next(it).base());
     270              :     }
     271              : }
     272              : 
     273       270827 : EngravingObject* EngravingObject::parent() const
     274              : {
     275       270827 :     return m_parent;
     276              : }
     277              : 
     278    116965375 : EngravingObject* EngravingObject::ownershipParent() const
     279              : {
     280    116965375 :     if (!m_parent || m_parent->isType(ElementType::DUMMY)) {
     281       825418 :         return nullptr;
     282              :     }
     283    116139957 :     return m_parent;
     284              : }
     285              : 
     286       158699 : void EngravingObject::setOwnershipParent(EngravingObject* p)
     287              : {
     288       158699 :     IF_ASSERT_FAILED(this != p) {
     289            0 :         return;
     290              :     }
     291              : 
     292       158699 :     if (!p) {
     293           94 :         moveToDummy();
     294           94 :         return;
     295              :     }
     296              : 
     297       158605 :     doSetParent(p);
     298       158605 :     if (m_parent) {
     299       158605 :         doSetScore(m_parent->score());
     300              :     }
     301              : }
     302              : 
     303     97182882 : Score* EngravingObject::score() const
     304              : {
     305     97182882 :     return m_score;
     306              : }
     307              : 
     308       280937 : MasterScore* EngravingObject::masterScore() const
     309              : {
     310       280937 :     return score()->masterScore();
     311              : }
     312              : 
     313            0 : bool EngravingObject::onSameScore(const EngravingObject* other) const
     314              : {
     315            0 :     return this->score() == other->score();
     316              : }
     317              : 
     318      1167407 : bool EngravingObject::isInScoreTree() const
     319              : {
     320      2771648 :     for (const EngravingObject* parent = ownershipParent(); parent; parent = parent->ownershipParent()) {
     321      2525554 :         if (parent->isScore()) {
     322       921313 :             return true;
     323              :         }
     324              :     }
     325       246094 :     return false;
     326              : }
     327              : 
     328     17044144 : const MStyle& EngravingObject::style() const
     329              : {
     330     17044144 :     return score()->style();
     331              : }
     332              : 
     333              : //---------------------------------------------------------
     334              : //   propertyDefault
     335              : //---------------------------------------------------------
     336              : 
     337       117783 : PropertyValue EngravingObject::propertyDefault(Pid pid) const
     338              : {
     339       117783 :     Sid sid = getPropertyStyle(pid);
     340       117783 :     if (sid != Sid::NOSTYLE) {
     341        41371 :         return styleValue(pid, sid);
     342              :     }
     343              :     //      LOGD("<%s>(%d) not found in <%s>", propertyQmlName(pid), int(pid), typeName());
     344        76412 :     return PropertyValue();
     345              : }
     346              : 
     347              : //---------------------------------------------------------
     348              : //   initElementStyle
     349              : //---------------------------------------------------------
     350              : 
     351        42173 : void EngravingObject::initElementStyle(const ElementStyle* ss)
     352              : {
     353        42173 :     m_elementStyle = ss;
     354        42173 :     size_t n      = m_elementStyle->size();
     355        42173 :     delete[] m_propertyFlagsList;
     356        42173 :     m_propertyFlagsList = new PropertyFlags[n];
     357       156597 :     for (size_t i = 0; i < n; ++i) {
     358       114424 :         m_propertyFlagsList[i] = PropertyFlags::STYLED;
     359              :     }
     360       156597 :     for (const StyledProperty& spp : *m_elementStyle) {
     361              :         //            setProperty(spp.pid, styleValue(spp.pid, spp.sid));
     362       114424 :         setProperty(spp.pid, styleValue(spp.pid, getPropertyStyle(spp.pid)));
     363              :     }
     364        42173 : }
     365              : 
     366              : //---------------------------------------------------------
     367              : //   resetProperty
     368              : //---------------------------------------------------------
     369              : 
     370        58383 : void EngravingObject::resetProperty(Pid pid)
     371              : {
     372        58383 :     PropertyValue v = propertyDefault(pid);
     373        58383 :     if (v.isValid()) {
     374        57990 :         setProperty(pid, v);
     375        57990 :         PropertyFlags p = propertyFlags(pid);
     376        57990 :         if (p == PropertyFlags::UNSTYLED) {
     377          158 :             setPropertyFlags(pid, PropertyFlags::STYLED);
     378              :         }
     379              :     }
     380        58383 : }
     381              : 
     382              : //---------------------------------------------------------
     383              : //   undoResetProperty
     384              : //---------------------------------------------------------
     385              : 
     386          861 : void EngravingObject::undoResetProperty(Pid id)
     387              : {
     388          861 :     PropertyFlags f = propertyFlags(id);
     389          861 :     if (f == PropertyFlags::UNSTYLED) {
     390            0 :         f = PropertyFlags::STYLED;
     391              :     }
     392          861 :     undoChangeProperty(id, propertyDefault(id), f);
     393          861 : }
     394              : 
     395              : //---------------------------------------------------------
     396              : //   isStyled
     397              : //---------------------------------------------------------
     398              : 
     399      1585586 : bool EngravingObject::isStyled(Pid pid) const
     400              : {
     401      1585586 :     PropertyFlags f = propertyFlags(pid);
     402      1585586 :     return f == PropertyFlags::STYLED;
     403              : }
     404              : 
     405              : //---------------------------------------------------------
     406              : //   changeProperty
     407              : //---------------------------------------------------------
     408              : 
     409         5837 : static void changeProperty(EngravingObject* e, Pid t, const PropertyValue& st, PropertyFlags ps)
     410              : {
     411         5837 :     if (e->getProperty(t) != st || e->propertyFlags(t) != ps) {
     412         3023 :         if (e->isBracketItem()) {
     413            3 :             BracketItem* bi = toBracketItem(e);
     414            3 :             e->score()->undo(new ChangeBracketProperty(bi->startStaff(), bi->column(), t, st, ps));
     415              :         } else {
     416         3020 :             e->score()->undo(new ChangeProperty(e, t, st, ps));
     417              :         }
     418              :     }
     419         5837 : }
     420              : 
     421              : //---------------------------------------------------------
     422              : //   changeProperties
     423              : //---------------------------------------------------------
     424              : 
     425         5656 : static void changeProperties(EngravingObject* object, Pid propertyId, const PropertyValue& propertyValue, PropertyFlags propertyFlag)
     426              : {
     427         5656 :     const std::list<EngravingObject*> linkList = object->linkListForPropertyPropagation();
     428        11798 :     for (EngravingObject* linkedObject : linkList) {
     429         6142 :         if (linkedObject == object) {
     430         5660 :             changeProperty(object, propertyId, propertyValue, propertyFlag);
     431         5660 :             continue;
     432              :         }
     433              : 
     434          482 :         if (!object->isEngravingItem() || !linkedObject->isEngravingItem()) {
     435            0 :             continue;
     436              :         }
     437              : 
     438          482 :         EngravingItem* item = toEngravingItem(object);
     439          482 :         EngravingItem* linkedItem = toEngravingItem(linkedObject);
     440          482 :         PropertyPropagation propertyPropagate = item->propertyPropagation(linkedItem, propertyId);
     441          482 :         switch (propertyPropagate) {
     442          275 :         case PropertyPropagation::NONE:
     443          275 :             break;
     444          173 :         case PropertyPropagation::PROPAGATE:
     445          173 :             changeProperty(linkedObject, propertyId, propertyValue, propertyFlag);
     446          173 :             break;
     447           34 :         case PropertyPropagation::UNLINK:
     448           34 :             item->unlinkPropertyFromMaster(propertyId);
     449           34 :             break;
     450            0 :         default:
     451            0 :             break;
     452              :         }
     453              :     }
     454              : 
     455         5656 :     if (!object->isEngravingItem() || propertyGroup(propertyId) == PropertyGroup::POSITION) {
     456           46 :         return;
     457              :     }
     458              : 
     459         5610 :     EngravingItem* item = toEngravingItem(object);
     460         5610 :     for (EngravingItem* originItem : item->originItems()) {
     461              :         // This is a shared item: propagate to all origin items
     462            0 :         changeProperty(originItem, propertyId, propertyValue, propertyFlag);
     463              :     }
     464         5610 :     if (EngravingItem* sharedItem = item->sharedItem(); sharedItem && sharedItem->originItems().front() == item) {
     465              :         // This is the first origin item of the shared item: propagate to shared item
     466            4 :         changeProperty(sharedItem, propertyId, propertyValue, propertyFlag);
     467              :     }
     468         5656 : }
     469              : 
     470              : //---------------------------------------------------------
     471              : //   undoChangeProperty
     472              : //---------------------------------------------------------
     473              : 
     474         5399 : void EngravingObject::undoChangeProperty(Pid id, const PropertyValue& v)
     475              : {
     476         5399 :     undoChangeProperty(id, v, propertyFlags(id));
     477         5399 : }
     478              : 
     479         6741 : void EngravingObject::undoChangeProperty(Pid id, const PropertyValue& v, PropertyFlags ps)
     480              : {
     481         6741 :     if ((getProperty(id) == v) && (propertyFlags(id) == ps)) {
     482         3912 :         return;
     483              :     }
     484         2829 :     if (id == Pid::TEXT_STYLE) {
     485              :         //
     486              :         // change a list of properties
     487              :         //
     488            0 :         auto l = textStyle(v.value<TextStyleType>());
     489              :         // Change to ElementStyle defaults
     490            0 :         for (const auto& p : *l) {
     491            0 :             if (p.sid == Sid::NOSTYLE) {
     492            0 :                 break;
     493              :             }
     494            0 :             changeProperties(this, p.pid, style().styleV(p.sid), PropertyFlags::STYLED);
     495              :         }
     496         2829 :     } else if (id == Pid::EXCLUDE_FROM_OTHER_PARTS) {
     497           12 :         if (isEngravingItem() && getProperty(Pid::EXCLUDE_FROM_OTHER_PARTS) != v) {
     498           12 :             EngravingItem* delegate = toEngravingItem(propertyDelegate(id));
     499           12 :             if (delegate) {
     500            0 :                 delegate->manageExclusionFromParts(v.toBool());
     501              :             } else {
     502           12 :                 toEngravingItem(this)->manageExclusionFromParts(v.toBool());
     503              :             }
     504              :         }
     505         2817 :     } else if (id == Pid::VOICE_ASSIGNMENT) {
     506            0 :         if (v.value<VoiceAssignment>() != VoiceAssignment::CURRENT_VOICE_ONLY) {
     507            0 :             changeProperties(this, Pid::VOICE, voice_idx_t(0), ps);
     508              :         }
     509              :     }
     510         2829 :     changeProperties(this, id, v, ps);
     511         2829 :     if (id != Pid::GENERATED) {
     512         2827 :         changeProperties(this, Pid::GENERATED, false, PropertyFlags::NOSTYLE);
     513              :     }
     514              : }
     515              : 
     516              : //---------------------------------------------------------
     517              : //   undoPushProperty
     518              : //---------------------------------------------------------
     519              : 
     520           21 : void EngravingObject::undoPushProperty(Pid id)
     521              : {
     522           21 :     PropertyValue val = getProperty(id);
     523              : 
     524           21 :     Transaction& tx = masterScore()->transactionManager()->currentOrDummyTransaction();
     525           21 :     tx.pushWithoutPerforming(new ChangeProperty(this, id, val));
     526           21 : }
     527              : 
     528              : //---------------------------------------------------------
     529              : //   reset
     530              : //---------------------------------------------------------
     531              : 
     532           23 : void EngravingObject::reset()
     533              : {
     534           63 :     for (const StyledProperty& spp : *styledProperties()) {
     535           40 :         undoResetProperty(spp.pid);
     536              :     }
     537           23 : }
     538              : 
     539              : //---------------------------------------------------------
     540              : //   linkTo
     541              : //    link this to element
     542              : //---------------------------------------------------------
     543         7168 : void EngravingObject::linkTo(EngravingObject* element)
     544              : {
     545         7168 :     assert(element != this);
     546         7168 :     assert(!m_links);
     547              : 
     548         7168 :     if (element->links()) {
     549         2428 :         setLinks(element->m_links);
     550         2428 :         assert(m_links->contains(element));
     551              :     } else {
     552         4740 :         setLinks(new LinkedObjects());
     553         4740 :         m_links->push_back(element);
     554         4740 :         element->setLinks(m_links);
     555              :     }
     556         7168 :     assert(!m_links->contains(this));
     557         7168 :     m_links->push_back(this);
     558         7168 : }
     559              : 
     560              : //---------------------------------------------------------
     561              : //   unlink
     562              : //---------------------------------------------------------
     563              : 
     564           44 : void EngravingObject::unlink()
     565              : {
     566           44 :     if (!m_links) {
     567           19 :         return;
     568              :     }
     569              : 
     570           25 :     assert(m_links->contains(this));
     571           25 :     m_links->remove(this);
     572              : 
     573              :     // if link list is empty, remove list
     574           25 :     if (m_links->size() <= 1) {
     575           18 :         if (!m_links->empty()) {
     576           17 :             m_links->front()->m_links = nullptr;
     577              :         }
     578           18 :         delete m_links;
     579              :     }
     580           25 :     m_links = 0;   // this element is not linked anymore
     581              : }
     582              : 
     583              : //---------------------------------------------------------
     584              : //   isLinked
     585              : ///  return true if se is different and
     586              : ///  linked to this element
     587              : //---------------------------------------------------------
     588              : 
     589         2284 : bool EngravingObject::isLinked(EngravingObject* se) const
     590              : {
     591         2284 :     if (se == this || !m_links) {
     592         1183 :         return false;
     593              :     }
     594              : 
     595         1101 :     if (se == nullptr) {
     596         1040 :         return !m_links->empty() && m_links->mainElement() != this;
     597              :     }
     598              : 
     599           61 :     return m_links->contains(se);
     600              : }
     601              : 
     602              : //---------------------------------------------------------
     603              : //   undoUnlink
     604              : //---------------------------------------------------------
     605              : 
     606         1164 : void EngravingObject::undoUnlink()
     607              : {
     608         1164 :     if (m_links) {
     609          535 :         score()->undo(new Unlink(this));
     610              :     }
     611         1164 : }
     612              : 
     613        23406 : void EngravingObject::setLinks(LinkedObjects* le)
     614              : {
     615        23406 :     m_links = le;
     616        23406 : }
     617              : 
     618              : //---------------------------------------------------------
     619              : //   linkList
     620              : //---------------------------------------------------------
     621              : 
     622        17573 : std::list<EngravingObject*> EngravingObject::linkList() const
     623              : {
     624        17573 :     std::list<EngravingObject*> el;
     625        17573 :     if (m_links) {
     626          874 :         el = *m_links;
     627              :     } else {
     628        16699 :         el.push_back(const_cast<EngravingObject*>(this));
     629              :     }
     630        17573 :     return el;
     631            0 : }
     632              : 
     633              : //---------------------------------------------------------
     634              : //   getPropertyFlagsIdx
     635              : //---------------------------------------------------------
     636              : 
     637      1885562 : int EngravingObject::getPropertyFlagsIdx(Pid id) const
     638              : {
     639      1885562 :     int i = 0;
     640      5247815 :     for (const StyledProperty& p : *m_elementStyle) {
     641      3467173 :         if (p.pid == id) {
     642       104920 :             return i;
     643              :         }
     644      3362253 :         ++i;
     645              :     }
     646      1780642 :     return -1;
     647              : }
     648              : 
     649              : //---------------------------------------------------------
     650              : //   propertyFlags
     651              : //---------------------------------------------------------
     652              : 
     653      2066721 : PropertyFlags EngravingObject::propertyFlags(Pid id) const
     654              : {
     655      2066721 :     if (EngravingObject* e = propertyDelegate(id)) {
     656        12752 :         return e->propertyFlags(id);
     657              :     }
     658              : 
     659              :     static PropertyFlags f = PropertyFlags::NOSTYLE;
     660              : 
     661      2053969 :     int i = getPropertyFlagsIdx(id);
     662      2053969 :     if (i == -1) {
     663      1839779 :         return f;
     664              :     }
     665       214190 :     return m_propertyFlagsList[i];
     666              : }
     667              : 
     668              : //---------------------------------------------------------
     669              : //   setPropertyFlags
     670              : //---------------------------------------------------------
     671              : 
     672        21918 : void EngravingObject::setPropertyFlags(Pid id, PropertyFlags f)
     673              : {
     674        21918 :     if (EngravingObject* e = propertyDelegate(id)) {
     675          124 :         e->setPropertyFlags(id, f);
     676          124 :         return;
     677              :     }
     678              : 
     679        21794 :     int i = getPropertyFlagsIdx(id);
     680        21794 :     if (i == -1) {
     681         4676 :         return;
     682              :     }
     683        17118 :     m_propertyFlagsList[i] = f;
     684              : }
     685              : 
     686              : //---------------------------------------------------------
     687              : //   getPropertyStyle
     688              : //---------------------------------------------------------
     689              : 
     690       237548 : Sid EngravingObject::getPropertyStyle(Pid id) const
     691              : {
     692      1755273 :     for (const StyledProperty& p : *m_elementStyle) {
     693      1681112 :         if (p.pid == id) {
     694       163387 :             return p.sid;
     695              :         }
     696              :     }
     697        74161 :     return Sid::NOSTYLE;
     698              : }
     699              : 
     700              : //---------------------------------------------------------
     701              : //   styleChanged
     702              : //---------------------------------------------------------
     703              : 
     704         9783 : void EngravingObject::styleChanged()
     705              : {
     706        41878 :     for (const StyledProperty& spp : *m_elementStyle) {
     707        32095 :         PropertyFlags f = propertyFlags(spp.pid);
     708        32095 :         if (f == PropertyFlags::STYLED) {
     709        31976 :             setProperty(spp.pid, styleValue(spp.pid, getPropertyStyle(spp.pid)));
     710              :         }
     711              :     }
     712         9783 : }
     713              : 
     714       103269 : const char* EngravingObject::typeName() const
     715              : {
     716       103269 :     return TConv::toXml(type()).ascii();
     717              : }
     718              : 
     719            0 : TranslatableString EngravingObject::typeUserName() const
     720              : {
     721            0 :     return TConv::capitalizedUserName(type());
     722              : }
     723              : 
     724            0 : String EngravingObject::translatedTypeUserName() const
     725              : {
     726            0 :     return typeUserName().translated();
     727              : }
     728              : 
     729       108189 : EID EngravingObject::eid() const
     730              : {
     731       108189 :     return masterScore()->eidRegister()->EIDFromItem(this);
     732              : }
     733              : 
     734        32127 : void EngravingObject::setEID(EID id) const
     735              : {
     736        32127 :     masterScore()->eidRegister()->registerItemEID(id, this);
     737        32127 : }
     738              : 
     739        70162 : EID EngravingObject::assignNewEID() const
     740              : {
     741        70162 :     return masterScore()->eidRegister()->newEIDForItem(this);
     742              : }
     743              : 
     744              : //---------------------------------------------------------
     745              : //   isSLineSegment
     746              : //---------------------------------------------------------
     747              : 
     748         5872 : bool EngravingObject::isSLineSegment() const
     749              : {
     750        11744 :     return isHairpinSegment() || isOttavaSegment() || isPedalSegment()
     751         5872 :            || isTrillSegment() || isVoltaSegment() || isTextLineSegment()
     752         5870 :            || isGlissandoSegment() || isLetRingSegment() || isVibratoSegment() || isPalmMuteSegment()
     753        11744 :            || isGradualTempoChangeSegment() || isWhammyBarSegment();
     754              : }
     755              : 
     756              : //---------------------------------------------------------
     757              : //   isText
     758              : //---------------------------------------------------------
     759              : 
     760      2841815 : bool EngravingObject::isTextBase() const
     761              : {
     762      2841815 :     return muse::contains(TEXTBASE_TYPES, type());
     763              : }
     764              : 
     765              : //---------------------------------------------------------
     766              : //   styleValue
     767              : //---------------------------------------------------------
     768              : 
     769      1120856 : PropertyValue EngravingObject::styleValue(Pid pid, Sid sid) const
     770              : {
     771      1120856 :     switch (propertyType(pid)) {
     772            0 :     case P_TYPE::ABSOLUTE:
     773            0 :         return style().styleAbsolute(sid);
     774          536 :     case P_TYPE::POINT: {
     775          536 :         PointF val = style().styleV(sid).value<PointF>();
     776          536 :         if (offsetIsSpatiumDependent()) {
     777          536 :             val *= style().spatium();
     778          536 :             if (isEngravingItem()) {
     779          534 :                 const EngravingItem* e = toEngravingItem(this);
     780          534 :                 if (e->staff() && !e->systemFlag()) {
     781            3 :                     val *= e->staff()->staffMag(e->tick());
     782              :                 }
     783              :             }
     784              :         } else {
     785            0 :             val *= DPMM;
     786              :         }
     787          536 :         return val;
     788              :     }
     789      1120320 :     default:
     790      1120320 :         return style().styleV(sid);
     791              :     }
     792              : }
     793              : }
        

Generated by: LCOV version 2.0-1