[trunk] Mid-measure bar lines in 1st stave lost by saving and re-loading

• Sep 13, 2011 - 04:39
Type
Functional
Severity
S2 - Critical
Status
closed
Project

Setup: rev. 4776; Ubuntu 11.04, Qt SDK 1.1.3 (Qt lib 4.7.4)

Steps:
1) Create a new score with at least two staves
2) Add some mid-measure bar lines in the first stave and some in the second
3) Save and re-load

Result: the mid-measure bar lines in the first stave do not show up; those in the second stave do.

Attachments:
1) An image is attached showing screen shots comparing step 2) and step 3) of a sample score
2) The sample score after saving once and after re-loading and saving a second time (this sample score shows a possible use of mid-measure bar lines for rendering multiple tempora across staves; it is not really musicologically correct, but only a quick hack).

Looking at the .mscx files shows that the mid-measure bar lines are there in the first save but missing in the second save.

Note:
This seems to happen because in file libmscore/measure.cpp, function void Measure::read(QDomElement e, int staffIdx), the test in line 1876:
    if ((score()->curTick != tick()) && (score()->curTick != (tick() + ticks())))
cannot really tell if the bar line is mid-measure or not during first stave reading.

While reading the first stave, the final ticks() call always return the tick length of the measure read so far and then score()->curTick is always equal to (tick() + ticks()) => the test fails and the bar line is considered an end-measure bar line and merged with the 'real' bar line (whence it is missing from the second save).

While reading any other stave, the total measure ticks have been established and the test succeeds for mid-measure bar lines.

A partial fix could be to rely on time signature to predict the total measure length:
    if ((score()->curTick != tick()) && (score()->curTick != (tick() + _timesig.ticks())))

This does not take into account irregular measures, though. And this, in turn, requires to re-introduce an explicit indication of the measure length for irregular measures (which was there and has been dropped at some point).

Priority set to critical as it leads to data loosing.

Thanks,

M.

P.S.: the statement
    barLine->setParent(this); //??
which seemed to puzzle some of the code maintainers is needed to know to which stave the bar line belongs precisely in case of a mid-measure bar line.


Comments

fixed in r 4788.
File format version incremented to 1.23: actual length of measure is written as property.

(barLine->setParen(this) is without effect: the staff is set with setTrack() and parent is set later in segment->add(xx),
barLine has Segment parent, not Measure parent)