Description

The Finale PDK Framework is a purely object-oriented layer around the Finale PDK to simplify plug-in programming for the Finale music notation product. Although the framework uses the Finale PDK to provide its function, very little knowledge about the Finale PDK should be required. One aim of the framework is to be fully documented all by itself.

The framework is also designed to provide possible hooks to object-oriented script languages like Ruby or Python.

The aims of the framework are:

  • to provide a very fast method to create Finale plug-ins

  • to provide logic and take care of complexities for the plug-in programmer

  • to provide excellent documentation to the programmer

  • to have a stable and easy maintainable code base

  • to be independent of the underlying Finale PDK version

  • to be able to create plug-ins that runs independently of the running Finale version

Requirements

This is the basic requirements for develop plug-ins with the Finale PDK Framework:

  • [C++] programming knowledge

  • A C++ development environment for Windows or Mac

  • A version of the Finale PDK Framework

  • A compatible version (PDK2010 or PDK2012) of the Finale PDK (from MakeMusic)

  • A version of Finale, to be able to test the plug-ins

Plugin

A Finale plug-in is a small program file that is loaded into Finale when Finale starts. A plug-in can expand Finale's functionality to the user.

NetBeans IDE (Windows)

Since NetBeans is made in Java and is portable between platform, similar instructions shuld work on Netbeans for Mac as well.

Dialog programming

To access the dialog classes, PDK_FRAMEWORK_DIALOGS code activation needs to be defined for the project.

In Windows, dialog resources are used. On the Mac, NIBs are used.

Main Documentation

The main reference for the Finale PDK is available at:
http://www.finaletips.nu/frameworkref/

Here you'll find documentation about classes, constants, hierarchies, and so on.

Framework design concepts

Compatibility

  • Ideally, the framework should compile and work with any version of the Finale PDK. Currently, the framework is compatible with the 2010PDK and 2012PDK. Generally, a higher PDK version is required if newer Finale features are needed. It's possible to create plug-ins that's runnable on earlier Finale versions than the PDK version, and the framework handle the version differences between the PDK version and the running Finale version.

  • String handling is handled automatically by the framework, though the FCString class (instead of char* for example). If Unicode is available (by the running Finale version and the PDK), the framework will use it. For example: if you're using the 2010PDK, Unicode will never be used (even on Finale versions that have Unicode support). And if you use the 2012PDK, Unicode will not be used by the framework if the plug-in is run on Finale 2011.

Classes

  • Class definitions should follow the naming conventions

  • Groups of classes that aren't almost always used by plug-ins should be activated by #defines to avoid code bloat

Finale API calls

  • Finale API calls should be encapsulated into relevant classes, instead of called directly.

Documentation

  • All documentation (Doxygen syntax) is put in the C++ header files.

  • Documentation is put before the definition/declaration.

  • Each definition that's documented should have a short \brief declaration. Any additional documentation goes in the next paragraph.

  • Parameters should be documented with a \param declaration

  • Return values should be documented with a \return declaration

  • Every class should belong to at least one group (the \ingroup declaration). The groups are defined in the pdkframework.h file.

 

Naming conventions

Naming Conventions for classes

  • All framework classes starts with the prefix FC. For example: FCString, FCMeasure, FCNote.

  • Appart from the FC prefix, a class name is in CamelCase. For example: FCStaffStyleDef, FCNoteEntry, FCTextExpressionDef.

  • Abstract classes that never should be used directly by a plug-in starts with the prefix __FC. For example: __FCBase, __FCBaseData, __FCNoInciOther.

  • Data collection classes specific to a type of object, has a plural s, compared to the object's class. For example: the collection class version of the FCPage class is FCPages.

  • Data browser classes specific to a type of object is named like the "collection version", but with the added suffix Browser. For example: the browser class version of the FCPage class is FCPagesBrowser.

  • In general, words are fully spelled out (and not abbreviated) in classes, if the word describes what the class mainly contains. The suffix Definition is always abbreviated as Def.

Naming Conventions for class methods

  • Names are in CamelCase

  • Methods intended for internal use start with an underscore character: '_'

  • Methods that return data values (that doesn't need to be deleted from heap) start with the prefix Get

  • Methods that create object(s) that must be deleted from the heap start with the prefix Create

  • Methods that set data values start with the prefix Set

  • Methods that is a boolean query start with the prefix Is

Naming Conventions for class members

  • Methods intended for internal use start with an underscore character: '_'

Code activation

Some of the classes or methods require code activation through #defines for the whole project. This makes the small, basic plug-ins much smaller.

  • PDK_FRAMEWORK_DEBUG - Debug methods for debugging support in the base classes, such as DebugOutDigit(), DebugOutBlock(), etc. On Windows, the DebugOutxxxx methods outputs to a separate console window. On the Mac, these methods goes to the console (within XCode for example).

  • PDK_FRAMEWORK_ENTRIES - Support for note entries and all related classes (such as note cells, layers, note-attached data).
  • PDK_FRAMEWORK_LAYOUT - Support for layout classes, such as FCPage and FCStaffSystem. FCMeasure is supported without this #define.
  • PDK_FRAMEWORK_PREFS - Access to the document preference settings classes
  • PDK_FRAMEWORK_DIAGNOSE - Automatic and detailed debug support for diagnostic purposes. If an operation fails, this option will output much information about the error. The PDK_FRAMEWORK_DEBUG #define must be set as well.
  • PDK_FRAMEWORK_FORMAT - Adds support for "Format" methods (that use the same syntax as the printf statement in C).
  • PDK_FRAMEWORK_SMARTSHAPES - Enables support for smart shapes.
  • PDK_FRAMEWORK_DIALOGS - Enables support for the dialog UI.
  • PDK_FRAMEWORK_ENIGMASTRINGS - Enables support for Enigma raw string methods in the string classes.
  • PDK_FRAMEWORK_SHAPES - Enable support for parsing and creation of shapes.
  • PDK_FRAMEWORK_COMPOSITETIMESIGS - Enable support for composite time signatures.
  • PDK_FRAMEWORK_NVWA - Enables cross-platform memory leak code through the "Stones of Nvwa" project on sourceforge: (http://sourceforge.net/projects/nvwa/). The project must link the debug_new.cpp file from that project.

 

Collection class

A collection class stores objects of the same kind in a collection, where each item can be identified by an index. It's very similar to an C++ array.

Browser class 

A browser class is a bit similar to a collection class. The difference is that while the a collection will keep all its items like an array, the browser class will not store any items in a permanent location.

The browser class parses through the Finale database, one item at a time.

A browser class are more memory efficient than a collection class, but it can get more time-consuming if the same records need processing more than once.

At some occasions browser classes are a superior choice, for example:

  • When the data objects need to be processed only once

  • When searching the Finale database for specific information

The Lock Page Layout Example shows the browser class in action. Here the browser approach was chosen, since each page only need to be processed once.

The most common method to use a browse class is with the ForEach method, since a browser class doesn't provide as many iteration methods as a collection class.

 

Iterator handler

Iterator handlers were inspired by the code block (or closure) concept in the great Ruby script programming language. They provide a mechanism to separate functionality from data storage in "collection-type" classes. With iterator handles, you first decide in what way to parse the collection, then you "send" the processing functionality to that particular parser.

Iterator handlers are used by both collection classes and browser classes. If the implementation of the iterator handler doesn't assume that the supplied data is stored in a certain way, iterator handles can be used interchangeably by both collection classes and browser classes.

Please note that iterator handlers are not covered by the type-safe linkage in C++. It's up to the programmer to make sure that the object type passed to the iterator handler is a known type. For example, sending measure objects to an iterator handle that assumes staff objects will most likely crash.