TAB's: first score measure not completely re-laid out if some staff props are changed

• Aug 22, 2012 - 00:22
S4 - Minor

Context: rev. 846d8f3 (2012-08-21) self-compiled with Qt SDK / Qt Lib 4.8.0 under Ubuntu 11.10 and Win 7

1) Open or create a score with a TAB staff
2) Open the ""Edit Staff/Part Properties" dlg box and from it the "Edit Staff Type" for the TAB staff in full config.
3a) Toggle the "Upside Down" check box
3b) Change "Notes Values" from "Note Symbols" to "Stems and Beams"
4) Accept the change

3a): all measures are flipped upside down, except the first which remains as it was
3b): in all measures, stems replace symbols, except the first where stems AND symbols cohexist

This happen BOTH in the preview window of the staff type dlg box (which just a mini-score) AND in the 'real' score itself.

Other changes in staff type properties are carried out in all measures, first one included.

By saving and re-opening the score, the lay out change is applied to the first measure too.

It seems as, when the score is re-laid out after the prop change, some lay out steps are carried from the first measure and some only from the second. I tried to follow the lay out work flow, but I got lost rather easily! :-(
I'll try again but any hint about where to specifically look will be very welcome!

I am aware that I should know what happen with tablatures, but this seems an interaction between some assumption in the general code and some in the tablature-specific code.



I think I find the source of the issue:

In function Measure::systemHeader() (file libmscore/measure.cpp), a measure is identified as having a system header or not by its first segment being a clef segment.

If a system only contains TAB staves, it may lack a clef segment (TAB staves may be clef-less). So, the first measure is not recognized as being the first and, at the beginning of function Measure::layoutStage1(), its _minWidth1 is cleared rather than _minWidth2. This leads to Measure::minWidth2() doing nothing and some laying out of the measure being skipped.

I'll do some experiments to see if there is a quick way to fix this, but ultimately Measure::systemHeader() has to be changed. On the spot, I would propose something like:

bool Measure::systemHeader() const
System * sys = system();
return sys && (sys->measures().first() == this);

Any comment?


I am more and more sure Measure::systemHeader() is the culprit:

by changing the first statement of Measure::layoutStage1() from:

(systemHeader() ? _minWidth2 : _minWidth1) = 0.0;


_minWidth1 = _minWidth2 = 0.0;

the issue disappears.

I think the decrease in optimization by removing the test to be marginal, but the increase in reliability to be significant: isn't it the case to implement this change in any case?

Of course, Measure::systemHeader() has also to be fixed!


I have tried the Measure::systemHeader() fix shown in #1 above and it seems to work: I am making it into a pull request.