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:
parent
f1e56f0b0b
commit
a0ecbba225
51 changed files with 235 additions and 363 deletions
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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; }
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -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";
|
||||
|
|
Loading…
Reference in a new issue