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 : }
|