Lock Page Layout Example

This plug-in example "locks" the page layout. It uses a browser class to parse through the pages within the specified measure region. If no measure selection was specified by the user, the full document will be processed.

For the first measure at each page, the plug-in puts a 'Start New Page' attribute for that measure.


First, the class declaration of a custom iterator handler.

class FCMyIteratorHandler : public FCIteratorHandler
{
    bool lock;
    FCMusicRegion* pRegion;
public:    
    FCMyIteratorHandler(bool value, FCMusicRegion* pTheRegion) : FCIteratorHandler()
    {
        lock = value;
        pRegion = pTheRegion;
    }
 
    virtual bool Iterate(__FCBase* pObject);
};


The implementation of FCMyIteratorHandler::Iterate() provides the core functionality for the iterator handler. This code will be run once for each page when the browser runs.

Note that much of the functionality in this method actually deals with the Automatic Update Layout setting in Finale: data can be marked as "not updated" at any time, which means that for both the page data and measures a new page update much be required to get the required data.

bool FCMyIteratorHandler::Iterate(__FCBase* object)
{
    FCPage* pPage = (FCPage*) object;    
    FCStaffSystem staffsystem;
 
    /* Update the layout if necessary: */
    if (!pPage->GetFirstSystem()) pPage->UpdateLayout();
 
    if (staffsystem.Load(pPage->GetFirstSystem())) {
        twobyte measureno = staffsystem.GetFirstMeasure();
        if (!measureno)
        {
            /* Update the layout if necessary: */
            pPage->UpdateLayout();
            if (!staffsystem.Load(pPage->GetFirstSystem())) return true;
        }
        measureno = staffsystem.GetFirstMeasure();
        if (pRegion->IsMeasureIncluded(measureno)) {
            /* Set the page break if it's in the region that should be processed: */
            FCMeasure measure;
            if (measure.Load(measureno)) {
                measure.SetPageBreak(lock);
                measure.Save();
            }
        }
    }
    return true;  // Continue with next page
}


The code to browse through the pages and use the iterator handler becomes pretty simple. The browser is set up statically, which is used to call all pages by using the custom iterator object. The ForEach() method call (highlighted below) is the row where the iterator handler is activated.

void LockPages(FCMusicRegion* pRegion, bool lock)
{
    FCBrowserPages pages;        
    FCMyIteratorHandler *pMyIteratorHandler = new FCMyIteratorHandler(lock, pRegion);    
    pages.ForEach(pMyIteratorHandler);    delete pMyIteratorHandler;
}

 

Mute Notes Example

This plug-in will mute or turn on playback for entries in a selected region. To achieve this, very few lines of code is needed!


The class declaration of the custom iterator handler:

class FCEntryPlaybackIH : public FCIteratorHandler
{
    bool playback;
public:
    FCEntryPlaybackIH(bool shouldplayback) : FCIteratorHandler()
        { playback = shouldplayback; }
    virtual bool Iterate(__FCBase* object);
};


The implementation of the Iterate method. The method returns true to signal that the next entry whould be processed (resulting in that all entries are processed).

bool FCEntryPlaybackIH::Iterate(__FCBase* object)
{
    FCNoteEntry* pEntry = (FCNoteEntry*) object;
    if (pEntry->IsNote()) pEntry->SetPlayback(playback);
    return true;
}


The part that runs the iterator handler for the region looks like this. A browser is used for the note entries, since there's no need to collect all the entries into a collection. The playback parameter decides if the entries should be played back or be muted.

void MuteOrUnmuteNotes(FCMusicRegion* pRegion, bool playback)
{
    FCBrowserNoteEntries browser;
    FCEntryPlaybackIH myIteratorHandler(playback);
    myIteratorHandler.SetSaveAfterIterate(true);
    browser.ForEachInRegion(&myIteratorHandler, pRegion);
}

 

Double Barlines Example

This plug-in will put double barlines and break multi-measure rests at all key signature changes. It will not put double barlines when there's a minor/major key change but with accidentals unchanged, although this behavior is easy to change.

The example shows both the use of a collection class and a iterator handler. Please note that the implementation of the iterator handler assumes that a collection is used - it has to be modified if a browser class is used.


The definition the the iterator handler looks like this:

class FCDblBarlineIteratorHandler : public FCIteratorHandler
{
     FCKeySignature* pPrevKey; /* A pointer to the previous key sig */
     FCMeasure* pPrevMeasure;  /* A pointer to the previous
                               * measure in the measure collection */
public:
    FCDblBarlineIteratorHandler() : FCIteratorHandler()
    {
        pPrevKey = NULL;
        pPrevMeasure = NULL;
    }    
    virtual bool Iterate(__FCBase* pObject);
};



The implementation of the Iterate method in the iterator handler looks like this. If you would like the plug-in to put double barlines for any kind of key change (even when there's just a minor/major mode change), change the highlighted rows below into if ((pPrevKey->GetKeyID() != pNewKey->GetKeyID()).

Note that the implementation assumes that there's a collection of measures, since the pPrevMeasure will point to the previously measure processed in the collection. Also, please note that since the previous measure will still exist in the collection, the pointer to the previous key signature will also still be available.

bool FCDblBarlineIteratorHandler::Iterate(__FCBase* pObject)
{
    FCMeasure* pMeasure = (FCMeasure*) pObject;       
    FCKeySignature *pNewKey = pMeasure->GetKeySignature();
    if (pPrevKey)
    {
        if ((pPrevKey->CalcSharps() != pNewKey->CalcSharps()) ||
 (pPrevKey->CalcFlats() != pNewKey->CalcFlats()))
{ pPrevMeasure->SetBarline(FCMeasure::BARLINE_DOUBLE); pPrevMeasure->SetBreakMMRest(true); pPrevMeasure->Save(); } } pPrevKey = pNewKey; pPrevMeasure = pMeasure; return true; }


The code for using the iterator handler on a measure collection follows. It loads the measures in the supplied region, and then calls the Iterate method once for each measure.

void DoubleBarlines(FCMusicRegion* pRegion)
{
    FCMeasures measures;
    measures.LoadRegion(pRegion);
    FCDblBarlineIteratorHandler myIteratorHandler;
    measures.ForEach(&myIteratorHandler);
}