Need help with cloning spanner segments

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view

Need help with cloning spanner segments

I have found no useful documentation of the MuseScore data structures and their proper use and the problem I have run into is not something that can be easily explained on IRC.

I am working in version 2.0.3-1. In excerpt.cpp, there is a method called cloneSpanner(). I'd like to create a version of this method that retains the user adjustments. Depending on how it works out, I might propose including it in 2.0.4 or I might decide that it's not worth bothering with. Consider this a test prototype.

The cloneSpanner() method appears to clone the Spanner and not the SpannerSegments. My first guess is that the SpannerSegments are created at some later time, by a call to layout().

One approach I tried was to clone the segments and add then add the cloned segments to the cloned spanner. This appears to give good results. I am guessing that if, in the part, there need to be more or fewer segments, the future call to layout() will add or delete them as necessary. This seems to be happening. The problem is that if I scale a staff in the score, the spanners are scaled in the part, so the cloned segments are somehow still tied to the original staves. Guessing again, I believe that the cloned segments are still pointing to the original Systems.

I have tried setting the cloned segments to have a null System parent: nspn->setSystem(0). Strangely, this doesn't change  the behavior at all; a scale change to the score staff still affects the part, even thought setSystem(0) should unparent the segment from its original System.

Determining the correct System to use for the cloned segments is way beyond me. I was hoping that setSystem(0) would clue some later piece of code (layout()?) to fix the system parents. Obviously, the segments have to revised upon various layout changes, so this doesn't seem far-fetched.

An alternate approach is to force creation of the segments by calling layout on the cloned Spanner and then for each segment in the source that has a match in the destination, copy the user adjustments. The problem with this is that calling layout() on a SlurTie creates SpannerSegments but calling it on a Hairpin does not. Also, when I tried to copy the grips on a SlurTie using

  nseg->setGrip(Grip::START, seg->getGrip(Grip::START));

the program SEGVs.

Somewhere, there is a piece of code that takes a Spanner and creates the appropriate SpannerSegments for it. The code I've found that I think performs this task seems to set the System parent to 0, which is what I tried to do without success.

Another conceptual problem I have is that the excerpt code goes to great lengths to adjust the cloned SlurTie's starting and ending ChordRests to point to ChordRests in the copied staff. One would assume that this would be the same for all Spanners, but Hairpins, for example, do not get the same treatment. I have no idea why.

There also seems to be some indication that some Spanners may not be anchored to ChordRests, but I have no idea which ones might be anchored to some other elements.

The process of creating an excerpt is one which requires a deep understand of the data structures and probably not the best first piece of code to tackle. I have spent days trying to unravel the structures by examining the code, but it is not at all easy to reverse engineer the documentation from the code, so help would be appreciated.