Reimplement scanElements function using score tree

Now its just a simple iteration over generic children, rather than
having to specify each child manually as we did before. This makes the
code simpler, and we have to override the virtual function in fewer
places.

Also,  whether an element should be scanned or not is now checked
in the child class rather than the parent class. E.g. showLedgerLines()
is checked in LedgerLines class now, instead of Chord, etc.
This commit is contained in:
Kumar Kartikay 2020-07-20 19:52:11 +05:30
parent f1e56f0b0b
commit a0ecbba225
51 changed files with 235 additions and 363 deletions

View file

@ -506,15 +506,11 @@ void Ambitus::draw(QPainter* p) const
// scanElements
//---------------------------------------------------------
void Ambitus::scanElements(void* data, void (* func)(void*, Element*), bool /*all*/)
void Ambitus::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
Q_UNUSED(all);
ScoreElement::scanElements(data, func, all);
func(data, this);
if (_topAccid.accidentalType() != AccidentalType::NONE) {
func(data, &_topAccid);
}
if (_bottomAccid.accidentalType() != AccidentalType::NONE) {
func(data, &_bottomAccid);
}
}
//---------------------------------------------------------

View file

@ -1519,10 +1519,8 @@ void BarLine::scanElements(void* data, void (* func)(void*, Element*), bool all)
if (width() == 0.0 && !all) {
return;
}
ScoreElement::scanElements(data, func, all);
func(data, this);
for (Element* e : _el) {
e->scanElements(data, func, all);
}
}
//---------------------------------------------------------

View file

@ -2708,4 +2708,17 @@ void Beam::startDrag(EditData& editData)
{
initBeamEditData(editData);
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Beam::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
ChordRest* cr = toChordRest(treeParent());
if (!all && cr->measure()->stemless(cr->staffIdx())) {
return;
}
Element::scanElements(data, func, all);
}
}

View file

@ -86,6 +86,8 @@ public:
ScoreElement* treeChild(int idx) const override;
int treeChildCount() const override;
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
Beam* clone() const override { return new Beam(*this); }
ElementType type() const override { return ElementType::BEAM; }
QPointF pagePos() const override; ///< position in page coordinates

View file

@ -60,6 +60,18 @@ void Box::layout()
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Box::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
ScoreElement::scanElements(data, func, all);
if (all || visible() || score()->showInvisible()) {
func(data, this);
}
}
//---------------------------------------------------------
// computeMinWidth
//---------------------------------------------------------

View file

@ -45,6 +45,9 @@ class Box : public MeasureBase
public:
Box(Score*);
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
virtual void draw(QPainter*) const override;
virtual bool isEditable() const override { return true; }

View file

@ -114,18 +114,6 @@ void BSymbol::remove(Element* e)
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void BSymbol::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
func(data, this);
foreach (Element* e, _leafs) {
e->scanElements(data, func, all);
}
}
//---------------------------------------------------------
// acceptDrop
//---------------------------------------------------------

View file

@ -39,7 +39,6 @@ public:
virtual void add(Element*) override;
virtual void remove(Element*) override;
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
virtual bool acceptDrop(EditData&) const override;
virtual Element* drop(EditData&) override;
virtual void layout() override;

View file

@ -1229,49 +1229,6 @@ qreal Chord::centerX() const
return x;
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Chord::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
for (Articulation* a : _articulations) {
func(data, a);
}
if (_hook) {
func(data, _hook);
}
if (_stem) {
func(data, _stem);
}
if (_stemSlash) {
func(data, _stemSlash);
}
if (_arpeggio) {
func(data, _arpeggio);
}
if (_tremolo && (tremoloChordType() != TremoloChordType::TremoloSecondNote)) {
func(data, _tremolo);
}
const Staff* st = staff();
if ((st && st->showLedgerLines(tick())) || !st) { // also for palette
for (LedgerLine* ll = _ledgerLines; ll; ll = ll->next()) {
func(data, ll);
}
}
size_t n = _notes.size();
for (size_t i = 0; i < n; ++i) {
_notes.at(i)->scanElements(data, func, all);
}
for (Chord* chord : _graceNotes) {
chord->scanElements(data, func, all);
}
for (Element* e : el()) {
e->scanElements(data, func, all);
}
ChordRest::scanElements(data, func, all);
}
//---------------------------------------------------------
// processSiblings
//---------------------------------------------------------

View file

@ -189,7 +189,6 @@ public:
void setNoteType(NoteType t) { _noteType = t; }
bool isGrace() const { return _noteType != NoteType::NORMAL; }
void toGraceAfter();
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
void setTrack(int val) override;

View file

@ -119,29 +119,6 @@ ChordRest::~ChordRest()
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void ChordRest::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (_beam && (_beam->elements().front() == this)
&& !measure()->stemless(staffIdx())) {
_beam->scanElements(data, func, all);
}
for (Lyrics* l : _lyrics) {
l->scanElements(data, func, all);
}
DurationElement* de = this;
while (de->tuplet() && de->tuplet()->elements().front() == de) {
de->tuplet()->scanElements(data, func, all);
de = de->tuplet();
}
if (_tabDur) {
func(data, _tabDur);
}
}
//---------------------------------------------------------
// writeProperties
//---------------------------------------------------------

View file

@ -89,7 +89,6 @@ public:
virtual void writeProperties(XmlWriter& xml) const;
virtual bool readProperties(XmlReader&);
virtual void readAddConnector(ConnectorInfoReader* info, bool pasteMode) override;
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
void setBeamMode(Beam::Mode m) { _beamMode = m; }
void undoSetBeamMode(Beam::Mode m);

View file

@ -228,12 +228,20 @@ void Element::deleteLater()
//---------------------------------------------------------
// scanElements
/// If leaf node, apply `func` on this element (after checking if it is visible).
/// Otherwise, recurse over all children (see ScoreElement::scanElements).
/// Note: This function is overridden in some classes to skip certain children,
/// or to apply `func` even to non-leaf nodes.
//---------------------------------------------------------
void Element::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || visible() || score()->showInvisible()) {
func(data, this);
if (treeChildCount() == 0) {
if (all || visible() || score()->showInvisible()) {
func(data, this);
}
} else {
ScoreElement::scanElements(data, func, all);
}
}

View file

@ -443,7 +443,7 @@ public:
mutable bool itemDiscovered { false }; ///< helper flag for bsp
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true);
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
virtual void reset() override; // reset all properties & position to default

View file

@ -1283,11 +1283,8 @@ Element* FretDiagram::drop(EditData& data)
void FretDiagram::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
Q_UNUSED(all);
ScoreElement::scanElements(data, func, all);
func(data, this);
// don't display harmony in palette
if (_harmony && !!parent()) {
func(data, _harmony);
}
}
//---------------------------------------------------------

View file

@ -200,21 +200,6 @@ LineSegment* Glissando::createLineSegment()
return seg;
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Glissando::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
func(data, this);
// don't scan segments belonging to systems; the systems themselves will scan them
for (SpannerSegment* seg : spannerSegments()) {
if (!seg->parent() || !seg->parent()->isSystem()) {
seg->scanElements(data, func, all);
}
}
}
//---------------------------------------------------------
// layout
//---------------------------------------------------------

View file

@ -74,7 +74,7 @@ public:
Glissando* clone() const override { return new Glissando(*this); }
ElementType type() const override { return ElementType::GLISSANDO; }
LineSegment* createLineSegment() override;
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
void layout() override;
void write(XmlWriter&) const override;
void read(XmlReader&) override;

View file

@ -2299,4 +2299,17 @@ Sid Harmony::getPropertyStyle(Pid pid) const
}
return TextBase::getPropertyStyle(pid);
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Harmony::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
// don't display harmony in palette
if (!parent()) {
return;
}
func(data, this);
}
}

View file

@ -136,6 +136,8 @@ public:
void setLeftParen(bool leftParen) { _leftParen = leftParen; }
void setRightParen(bool rightParen) { _rightParen = rightParen; }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
Harmony* findNext() const;
Harmony* findPrev() const;
Fraction ticksTilNext(bool stopAtMeasureEnd = false) const;

View file

@ -151,4 +151,15 @@ QVariant InstrumentName::propertyDefault(Pid id) const
return TextBase::propertyDefault(id);
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void InstrumentName::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || sysStaff()->show()) {
func(data, this);
}
}
}

View file

@ -21,6 +21,7 @@ enum class InstrumentNameType : char {
};
class System;
class SysStaff;
//---------------------------------------------------------
// InstrumentName
@ -30,6 +31,7 @@ class InstrumentName final : public TextBase
{
InstrumentNameType _instrumentNameType;
int _layoutPos { 0 };
SysStaff* _sysStaff { nullptr };
public:
InstrumentName(Score*);
@ -47,6 +49,11 @@ public:
System* system() const { return toSystem(parent()); }
SysStaff* sysStaff() const { return _sysStaff; }
void setSysStaff(SysStaff* s) { _sysStaff = s; }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
Fraction playTick() const override;
bool isEditable() const override { return false; }
QVariant getProperty(Pid propertyId) const override;

View file

@ -133,4 +133,17 @@ bool LedgerLine::readProperties(XmlReader& e)
}
return true;
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void LedgerLine::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
Staff* st = chord()->staff();
if (st && !st->showLedgerLines(tick())) {
return;
}
Element::scanElements(data, func, all);
}
}

View file

@ -43,6 +43,8 @@ public:
QPointF pagePos() const override; ///< position in page coordinates
Chord* chord() const { return toChord(parent()); }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
qreal len() const { return _len; }
qreal lineWidth() const { return _width; }
void setLen(qreal v) { _len = v; }

View file

@ -64,19 +64,6 @@ Lyrics::~Lyrics()
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Lyrics::scanElements(void* data, void (* func)(void*, Element*), bool /*all*/)
{
func(data, this);
/* DO NOT ADD EITHER THE LYRICSLINE OR THE SEGMENTS: segments are added through the system each belongs to;
LyricsLine is not needed, as it is internally manged.
if (_separator)
_separator->scanElements(data, func, all); */
}
//---------------------------------------------------------
// write
//---------------------------------------------------------

View file

@ -65,7 +65,6 @@ public:
Lyrics* clone() const override { return new Lyrics(*this); }
ElementType type() const override { return ElementType::LYRICS; }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
bool acceptDrop(EditData&) const override;
Element* drop(EditData&) override;

View file

@ -2528,31 +2528,11 @@ bool Measure::isFirstInSystem() const
void Measure::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
MeasureBase::scanElements(data, func, all);
int nstaves = score()->nstaves();
for (int staffIdx = 0; staffIdx < nstaves; ++staffIdx) {
if (!all && !(visible(staffIdx) && score()->staff(staffIdx)->show())) {
continue;
for (ScoreElement* el : (*this)) {
if (el->isMeasure()) {
continue; // do not scan Measures 'inside' mmrest measure
}
MStaff* ms = _mstaves[staffIdx];
func(data, ms->lines());
if (ms->vspacerUp()) {
func(data, ms->vspacerUp());
}
if (ms->vspacerDown()) {
func(data, ms->vspacerDown());
}
if (ms->noText()) {
func(data, ms->noText());
}
}
for (Segment* s = first(); s; s = s->next()) {
if (!s->enabled()) {
continue;
}
s->scanElements(data, func, all);
el->scanElements(data, func, all);
}
}

View file

@ -91,35 +91,6 @@ MeasureBase::~MeasureBase()
qDeleteAll(_el);
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void MeasureBase::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (isMeasure()) {
for (Element* e : _el) {
if (score()->tagIsValid(e->tag())) {
if (e->staffIdx() >= score()->staves().size()) {
qDebug("MeasureBase::scanElements: bad staffIdx %d in element %s", e->staffIdx(), e->name());
}
if ((e->track() == -1) || e->systemFlag() || ((Measure*)this)->visible(e->staffIdx())) {
e->scanElements(data, func, all);
}
}
}
} else {
for (Element* e : _el) {
if (score()->tagIsValid(e->tag())) {
e->scanElements(data, func, all);
}
}
}
if (isBox()) {
func(data, this);
}
}
//---------------------------------------------------------
// add
/// Add new Element \a el to MeasureBase

View file

@ -107,7 +107,6 @@ public:
virtual void layout();
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true);
ElementList& el() { return _el; }
const ElementList& el() const { return _el; }
System* system() const { return (System*)parent(); }

View file

@ -2385,31 +2385,10 @@ QString Note::noteTypeUserName() const
void Note::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
func(data, this);
// tie segments are collected from System
// if (_tieFor && !staff()->isTabStaff(chord->tick())) // no ties in tablature
// _tieFor->scanElements(data, func, all);
for (Element* e : _el) {
if (score()->tagIsValid(e->tag())) {
e->scanElements(data, func, all);
}
ScoreElement::scanElements(data, func, all);
if (all || visible() || score()->showInvisible()) {
func(data, this);
}
for (Spanner* sp : _spannerFor) {
sp->scanElements(data, func, all);
}
if (!dragMode && _accidental) {
func(data, _accidental);
}
for (NoteDot* dot : _dots) {
func(data, dot);
}
// see above - tie segments are still collected from System!
// if (_tieFor && !_tieFor->spannerSegments().empty())
// _tieFor->spannerSegments().front()->scanElements(data, func, all);
// if (_tieBack && _tieBack->spannerSegments().size() > 1)
// _tieBack->spannerSegments().back()->scanElements(data, func, all);
}
//---------------------------------------------------------

View file

@ -221,13 +221,10 @@ void Page::styleChanged()
void Page::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
for (System* s :_systems) {
for (MeasureBase* m : s->measures()) {
m->scanElements(data, func, all);
}
s->scanElements(data, func, all);
ScoreElement::scanElements(data, func, all);
if (all || visible() || score()->showInvisible()) {
func(data, this);
}
func(data, this);
}
#ifdef USE_BSP

View file

@ -603,13 +603,7 @@ qreal Rest::downPos() const
void Rest::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
ChordRest::scanElements(data, func, all);
for (Element* e : el()) {
e->scanElements(data, func, all);
}
for (NoteDot* dot : m_dots) {
dot->scanElements(data, func, all);
}
ScoreElement::scanElements(data, func, all);
if (!isGap()) {
func(data, this);
}

View file

@ -1914,31 +1914,6 @@ Fraction Score::inputPos() const
return _is.tick();
}
//---------------------------------------------------------
// scanElements
// scan all elements
//---------------------------------------------------------
void Score::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
for (MeasureBase* mb = first(); mb; mb = mb->next()) {
mb->scanElements(data, func, all);
if (mb->type() == ElementType::MEASURE) {
Measure* m = toMeasure(mb);
Measure* mmr = m->mmRest();
if (mmr) {
mmr->scanElements(data, func, all);
}
}
}
for (Page* page : pages()) {
for (System* s :page->systems()) {
s->scanElements(data, func, all);
}
func(data, page);
}
}
//---------------------------------------------------------
// scanElementsInRange
//---------------------------------------------------------

View file

@ -1081,7 +1081,6 @@ public:
qreal point(const Spatium sp) const { return sp.val() * spatium(); }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true);
void scanElementsInRange(void* data, void (* func)(void*, Element*), bool all = true);
int fileDivision() const { return _fileDivision; } ///< division of current loading *.msc file
void splitStaff(int staffIdx, int splitPoint);

View file

@ -197,6 +197,19 @@ int ScoreElement::treeChildIdx(ScoreElement* child) const
return -1;
}
//---------------------------------------------------------
// scanElements
/// Recursively apply scanElements to all children.
/// See also Element::scanElements.
//---------------------------------------------------------
void ScoreElement::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
for (ScoreElement* child : (*this)) {
child->scanElements(data, func, all);
}
}
//---------------------------------------------------------
// propertyDefault
//---------------------------------------------------------

View file

@ -236,6 +236,8 @@ public:
static ElementType name2type(const QString& s) { return name2type(QStringRef(&s)); }
static const char* name(ElementType);
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true);
virtual QVariant getProperty(Pid) const = 0;
virtual bool setProperty(Pid, const QVariant&) = 0;
virtual QVariant propertyDefault(Pid) const;

View file

@ -1196,21 +1196,13 @@ Ms::Element* Segment::elementAt(int track) const
void Segment::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
for (int track = 0; track < score()->nstaves() * VOICES; ++track) {
int staffIdx = track / VOICES;
if (!all && !(measure()->visible(staffIdx) && score()->staff(staffIdx)->show())) {
track += VOICES - 1;
continue;
}
Element* e = element(track);
if (e == 0) {
continue;
}
e->scanElements(data, func, all);
if (!enabled()) {
return;
}
for (Element* e : annotations()) {
if (all || e->systemFlag() || measure()->visible(e->staffIdx())) {
e->scanElements(data, func, all);
for (ScoreElement* el : (*this)) {
Element* e = toElement(el);
if (all || e->systemFlag() || (score()->staff(e->staffIdx())->show() && measure()->visible(e->staffIdx()))) {
e->scanElements(data, func, all);
}
}
}

View file

@ -12,8 +12,10 @@
#include "spacer.h"
#include "score.h"
#include "staff.h"
#include "mscore.h"
#include "xml.h"
#include "measure.h"
namespace Ms {
//---------------------------------------------------------
@ -252,4 +254,15 @@ QVariant Spacer::propertyDefault(Pid id) const
return Element::propertyDefault(id);
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Spacer::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || (measure()->visible(staffIdx()) && score()->staff(staffIdx())->show())) {
func(data, this);
}
}
}

View file

@ -44,6 +44,7 @@ public:
Spacer* clone() const override { return new Spacer(*this); }
ElementType type() const override { return ElementType::SPACER; }
Measure* measure() const { return toMeasure(parent()); }
SpacerType spacerType() const { return _spacerType; }
void setSpacerType(SpacerType t) { _spacerType = t; }
@ -53,6 +54,8 @@ public:
void draw(QPainter*) const override;
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
bool isEditable() const override { return true; }
void startEditDrag(EditData&) override;
void editDrag(EditData&) override;

View file

@ -344,6 +344,17 @@ void SpannerSegment::triggerLayout() const
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void SpannerSegment::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || spanner()->eitherEndVisible()) {
func(data, this);
}
}
//---------------------------------------------------------
// Spanner
//---------------------------------------------------------
@ -489,17 +500,47 @@ void Spanner::insertTimeUnmanaged(const Fraction& fromTick, const Fraction& len)
//---------------------------------------------------------
// scanElements
// used in palettes
//---------------------------------------------------------
void Spanner::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
Q_UNUSED(all);
for (SpannerSegment* seg : segments) {
seg->scanElements(data, func, true);
for (ScoreElement* el : *this) {
if (treeParent() && el->isSpannerSegment()) {
continue; // spanner segments are scanned by the system
// except in the palette (in which case treeParent() == nullptr)
}
el->scanElements(data, func, all);
}
}
//---------------------------------------------------------
// isVisbleCR
//---------------------------------------------------------
static bool isVisibleCR(Element* e)
{
if (!e || !e->isChordRest()) {
return true; // assume visible
}
ChordRest* cr = toChordRest(e);
return cr->measure()->visible(cr->staffIdx());
}
//---------------------------------------------------------
// eitherEndVisible
//---------------------------------------------------------
bool Spanner::eitherEndVisible() const
{
if (isVolta()) {
return true;
}
if (!score()->staff(staffIdx())->show()) {
return false;
}
return isVisibleCR(startElement()) || isVisibleCR(endElement());
}
//---------------------------------------------------------
// setScore
//---------------------------------------------------------

View file

@ -107,6 +107,8 @@ public:
virtual void setVisible(bool f) override;
virtual void setColor(const QColor& col) override;
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
virtual Element* nextSegmentElement() override;
virtual Element* prevSegmentElement() override;
virtual QString accessibleInfo() const override;
@ -211,6 +213,7 @@ public:
size_t nsegments() const { return segments.size(); }
bool segmentsEmpty() const { return segments.empty(); }
void eraseSpannerSegments();
bool eitherEndVisible() const;
virtual SpannerSegment* layoutSystem(System*);
virtual void layoutSystemsDone();

View file

@ -143,4 +143,15 @@ qreal StaffLines::y1() const
*/
return system->staff(staffIdx())->y() + ipos().y();
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void StaffLines::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (all || (measure()->visible(staffIdx()) && score()->staff(staffIdx())->show())) {
func(data, this);
}
}
}

View file

@ -34,6 +34,8 @@ public:
QPointF pagePos() const override; ///< position in page coordinates
QPointF canvasPos() const override; ///< position in page coordinates
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
QVector<QLineF>& getLines() { return lines; }
Measure* measure() const { return (Measure*)parent(); }
qreal y1() const;

View file

@ -758,6 +758,7 @@ void System::layout2()
SysStaff* vs = staff(visible);
for (InstrumentName* t : s->instrumentNames) {
t->setTrack(visible * VOICES);
t->setSysStaff(vs);
vs->instrumentNames.append(t);
}
s->instrumentNames.clear();
@ -878,6 +879,7 @@ void System::setInstrumentNames(bool longName, Fraction tick)
iname = new InstrumentName(score());
// iname->setGenerated(true);
iname->setParent(this);
iname->setSysStaff(staff);
iname->setTrack(staffIdx * VOICES);
iname->setInstrumentNameType(longName ? InstrumentNameType::LONG : InstrumentNameType::SHORT);
iname->setLayoutPos(sn.pos());
@ -989,6 +991,7 @@ void System::add(Element* el)
case ElementType::INSTRUMENT_NAME:
// qDebug(" staffIdx %d, staves %d", el->staffIdx(), _staves.size());
_staves[el->staffIdx()]->instrumentNames.append(toInstrumentName(el));
toInstrumentName(el)->setSysStaff(_staves[el->staffIdx()]);
break;
case ElementType::BEAM:
@ -1074,6 +1077,7 @@ void System::remove(Element* el)
switch (el->type()) {
case ElementType::INSTRUMENT_NAME:
_staves[el->staffIdx()]->instrumentNames.removeOne(toInstrumentName(el));
toInstrumentName(el)->setSysStaff(0);
break;
case ElementType::BEAM:
score()->removeElement(el);
@ -1200,62 +1204,13 @@ MeasureBase* System::nextMeasure(const MeasureBase* m) const
//---------------------------------------------------------
// scanElements
// collect all visible elements
//---------------------------------------------------------
void System::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (vbox()) {
return;
}
for (Bracket* b : _brackets) {
func(data, b);
}
if (_systemDividerLeft) {
func(data, _systemDividerLeft);
}
if (_systemDividerRight) {
func(data, _systemDividerRight);
}
int idx = 0;
for (const SysStaff* st : _staves) {
if (all || st->show()) {
for (InstrumentName* t : st->instrumentNames) {
func(data, t);
}
}
++idx;
}
ScoreElement::scanElements(data, func, all);
for (SpannerSegment* ss : _spannerSegments) {
int staffIdx = ss->spanner()->staffIdx();
if (staffIdx == -1) {
qDebug("System::scanElements: staffIDx == -1: %s %p", ss->spanner()->name(), ss->spanner());
staffIdx = 0;
}
bool v = true;
Spanner* spanner = ss->spanner();
if (spanner->anchor() == Spanner::Anchor::SEGMENT || spanner->anchor() == Spanner::Anchor::CHORD) {
Element* se = spanner->startElement();
Element* ee = spanner->endElement();
bool v1 = true;
if (se && se->isChordRest()) {
ChordRest* cr = toChordRest(se);
Measure* m = cr->measure();
v1 = m->visible(cr->staffIdx());
}
bool v2 = true;
if (!v1 && ee && ee->isChordRest()) {
ChordRest* cr = toChordRest(ee);
Measure* m = cr->measure();
v2 = m->visible(cr->staffIdx());
}
v = v1 || v2; // hide spanner if both chords are hidden
}
if (all || (score()->staff(staffIdx)->show() && _staves[staffIdx]->show() && v) || spanner->isVolta()) {
ss->scanElements(data, func, all);
}
ss->scanElements(data, func, all);
}
}

View file

@ -114,16 +114,6 @@ void TBox::read(XmlReader& e)
}
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void TBox::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
_text->scanElements(data, func, all);
Box::scanElements(data, func, all);
}
//---------------------------------------------------------
// drop
//---------------------------------------------------------

View file

@ -47,7 +47,6 @@ public:
virtual void remove(Element* el) override;
virtual void layout();
virtual void scanElements(void* data, void (* func)(void*, Element*), bool all=true);
virtual QString accessibleExtraInfo() const override;
Text* text() { return _text; }

View file

@ -778,4 +778,16 @@ QString Tremolo::propertyUserValue(Pid pid) const
}
return Element::propertyUserValue(pid);
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Tremolo::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (chord() && chord()->tremoloChordType() == TremoloChordType::TremoloSecondNote) {
return;
}
Element::scanElements(data, func, all);
}
}

View file

@ -65,6 +65,8 @@ public:
int subtype() const override { return static_cast<int>(_tremoloType); }
QString subtypeName() const override;
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
QString tremoloTypeName() const;
void setTremoloType(const QString& s);
static TremoloType name2Type(const QString& s);

View file

@ -232,21 +232,6 @@ Element* TrillSegment::propertyDelegate(Pid pid)
return LineSegment::propertyDelegate(pid);
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void TrillSegment::scanElements(void* data, void (* func)(void*, Element*), bool /*all*/)
{
func(data, this);
if (isSingleType() || isBeginType()) {
Accidental* a = trill()->accidental();
if (a) {
func(data, a);
}
}
}
//---------------------------------------------------------
// getPropertyStyle
//---------------------------------------------------------
@ -454,19 +439,6 @@ QString Trill::trillTypeUserName() const
return qApp->translate("trillType", trillTable[static_cast<int>(trillType())].userName.toUtf8().constData());
}
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void Trill::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (_accidental) {
_accidental->scanElements(data, func, all);
}
func(data, this); // ?
SLine::scanElements(data, func, all);
}
//---------------------------------------------------------
// getProperty
//---------------------------------------------------------

View file

@ -50,7 +50,6 @@ public:
void add(Element*) override;
void remove(Element*) override;
void scanElements(void* data, void (* func)(void*, Element*), bool all) override;
Shape shape() const override;
std::vector<SymId> symbols() const { return _symbols; }
@ -110,7 +109,6 @@ public:
void setAccidental(Accidental* a) { _accidental = a; }
Segment* segment() const { return (Segment*)parent(); }
void scanElements(void* data, void (* func)(void*, Element*), bool all=true) override;
QVariant getProperty(Pid propertyId) const override;
bool setProperty(Pid propertyId, const QVariant&) override;

View file

@ -757,10 +757,15 @@ Shape Tuplet::shape() const
void Tuplet::scanElements(void* data, void (* func)(void*, Element*), bool all)
{
if (_number && all) {
func(data, _number);
for (ScoreElement* child : *this) {
if (child == _number && !all) {
continue; // don't scan number unless all is true
}
child->scanElements(data, func, all);
}
if (all || visible() || score()->showInvisible()) {
func(data, this);
}
func(data, this);
}
//---------------------------------------------------------

View file

@ -30,13 +30,9 @@ class TestTreeModel : public QObject, public MTest
{
Q_OBJECT
MasterScore * score;
void beam(const char* path);
void tstTree(QString file);
void traverseTree(ScoreElement* element);
QString elementToText(ScoreElement* element);
private slots:
void initTestCase();
void tstTreeElements() { tstTree("layout_elements.mscx"); }
@ -45,6 +41,8 @@ private slots:
void tstTreeGoldberg() { tstTree("goldberg.mscx"); }
};
QString elementToText(ScoreElement* element);
//---------------------------------------------------------
// initTestCase
//---------------------------------------------------------
@ -103,7 +101,7 @@ void TestTreeModel::traverseTree(ScoreElement* element)
/// for printing debug info about any element
//---------------------------------------------------------
QString TestTreeModel::elementToText(ScoreElement* element)
QString elementToText(ScoreElement* element)
{
if (element == nullptr) {
return "nullptr";