Fix #286707: add scores and Score.name back to plugin API

Also adding more APIs and some documentation for them.
And some more changes to the existing plugins and documentation.
This commit is contained in:
Joachim Schmitz 2019-05-17 11:57:20 +02:00
parent 53a5bfa34f
commit 1aa445eea2
15 changed files with 107 additions and 70 deletions

View file

@ -58,13 +58,13 @@ MuseScore {
Here is what happens here.
- `import MuseScore 3.0` is necessary to use MuseScore API in QML code.
- The `MuseScore { ... }` statement delares an object of `MuseScore` type (\ref
- The `MuseScore { ... }` statement declares an object of `MuseScore` type (\ref
Ms::PluginAPI::PluginAPI is exposed to QML as `MuseScore`). This should be
the root object of any QML plugin for MuseScore.
- Statements like `menuPath: "Plugins.pluginName"` assign properties to that
object, see \ref
Ms::PluginAPI::PluginAPI "the class reference" for the meaning of those
properties. Apart those properties listed in that page, you can assign any
properties. Apart from the properties listed in that page, you can assign any
other properties and/or declare other QML objects too.
- `onRun()` is the function that is invoked when the plugin is executed (via a
menu entry or via a shortcut). This is the entry point of your plugin.

View file

@ -51,7 +51,7 @@ Most of enumerations exposed to QML plugins remain the same but some were rename
**GlissandoStyle.CHROMATIC** etc.
- **TextStyleType** → \ref Ms::PluginAPI::PluginAPI::Tid "**Tid**"
- **TextStyleType** → \ref Ms::PluginAPI::PluginAPI::Tid "Tid"
- \ref Ms::PluginAPI::PluginAPI::NoteHeadType "NoteHeadType" \par
**HEAD_AUTO, HEAD_WHOLE, HEAD_HALF, HEAD_QUARTER, HEAD_BREVIS, HEAD_TYPES** are now in **NoteHeadType** enumeration.

View file

@ -48,14 +48,14 @@ enum class PlayEventType : char {
/// Graphic representation of a chord.
/// Single notes are handled as degenerated chords.
//
// @P beam Beam the beam of the chord if any (read only)
// @P graceNotes array[Chord] the list of grace note chords (read only)
// @P hook Hook the hook of the chord if any (read only)
// @P lyrics array[Lyrics] the list of lyrics (read only)
// @P notes array[Note] the list of notes (read only)
// @P stem Stem the stem of the chord if any (read only)
// @P stemSlash StemSlash the stem slash of the chord (acciaccatura) if any (read only)
// @P stemDirection Direction the stem slash of the chord (acciaccatura) if any (read only)
// @P beam Beam the beam of the chord, if any (read only)
// @P graceNotes array[Chord] the list of grace note chords (read only)
// @P hook Hook the hook of the chord, if any (read only)
// @P lyrics array[Lyrics] the list of lyrics (read only)
// @P notes array[Note] the list of notes (read only)
// @P stem Stem the stem of the chord, if any (read only)
// @P stemSlash StemSlash the stem slash of the chord (acciaccatura), if any (read only)
// @P stemDirection Direction the stem direction of the chord: AUTO, UP, DOWN (read only)
//---------------------------------------------------------
class Chord final : public ChordRest {

View file

@ -2602,7 +2602,7 @@ void Score::cmdExplode()
int full = 0;
for (Segment* seg = startSegment; seg && seg->tick() < lTick; seg = seg->next1()) {
for (int i = srcTrack; i < srcTrack + VOICES && full != VOICES; i ++) {
for (int i = srcTrack; i < srcTrack + VOICES && full != VOICES; i++) {
bool t = true;
for (int j = 0; j < VOICES; j++) {
if (i == sTracks[j]) {

View file

@ -44,9 +44,9 @@ class Cursor : public QObject {
Q_OBJECT
/** Current track */
Q_PROPERTY(int track READ track WRITE setTrack)
/** Current staff (track / 4) */
/** Current staff (#track / 4) */
Q_PROPERTY(int staffIdx READ staffIdx WRITE setStaffIdx)
/** Current voice (track % 4) */
/** Current voice (#track % 4) */
Q_PROPERTY(int voice READ voice WRITE setVoice)
/**
* Segment type filter, a bitmask from

View file

@ -62,11 +62,11 @@ class PluginAPI : public Ms::QmlPlugin {
Q_PROPERTY(QString version READ version WRITE setVersion)
/** Human-readable plugin description, displayed in Plugin Manager */
Q_PROPERTY(QString description READ description WRITE setDescription)
/** type may be dialog, dock, or not defined */
/** Type may be dialog, dock, or not defined */
Q_PROPERTY(QString pluginType READ pluginType WRITE setPluginType)
/** Where to dock on main screen. Possible values: left, top, bottom, right */
Q_PROPERTY(QString dockArea READ dockArea WRITE setDockArea)
/** Whether the plugin requires an existing score to run */
/** Whether the plugin requires an existing score to run, default is `true` */
Q_PROPERTY(bool requiresScore READ requiresScore WRITE setRequiresScore)
/** Number of MIDI ticks for 1/4 note (read only) */
Q_PROPERTY(int division READ division)
@ -80,9 +80,10 @@ class PluginAPI : public Ms::QmlPlugin {
Q_PROPERTY(int mscoreUpdateVersion READ mscoreUpdateVersion CONSTANT)
/** (read-only) */
Q_PROPERTY(qreal mscoreDPI READ mscoreDPI)
/** current score, if any (read only) */
/** Current score, if any (read only) */
Q_PROPERTY(Ms::PluginAPI::Score* curScore READ curScore)
//TODO-ws Q_PROPERTY(QQmlListProperty<Ms::Score> scores READ scores)
/** List of currently open scores (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Score> scores READ scores)
// Should be initialized in qmlpluginapi.cpp
/// Contains Ms::ElementType enumeration values
@ -115,7 +116,7 @@ class PluginAPI : public Ms::QmlPlugin {
DECLARE_API_ENUM( OrnamentStyle, ornamentStyleEnum )
/// Contains Ms::GlissandoStyle enumeration values
/// \note In MuseScore 2.X this enumeration was available as
/// MScoreCHROMATIC, MScore.WHITE_KEYS, MScore.BLACK_KEYS,
/// MScore.CHROMATIC, MScore.WHITE_KEYS, MScore.BLACK_KEYS,
/// MScore.DIATONIC.
DECLARE_API_ENUM( GlissandoStyle, glissandoStyleEnum )
/// Contains Ms::Tid enumeration values

View file

@ -92,6 +92,15 @@ Measure* Score::firstMeasure()
return wrap<Measure>(score()->firstMeasure(), Ownership::SCORE);
}
//---------------------------------------------------------
// Score::firstMeasureMM
//---------------------------------------------------------
Measure* Score::firstMeasureMM()
{
return wrap<Measure>(score()->firstMeasureMM(), Ownership::SCORE);
}
//---------------------------------------------------------
// Score::lastMeasure
//---------------------------------------------------------
@ -100,5 +109,14 @@ Measure* Score::lastMeasure()
{
return wrap<Measure>(score()->lastMeasure(), Ownership::SCORE);
}
//---------------------------------------------------------
// Score::firstMeasureMM
//---------------------------------------------------------
Measure* Score::lastMeasureMM()
{
return wrap<Measure>(score()->lastMeasureMM(), Ownership::SCORE);
}
}
}

View file

@ -31,39 +31,54 @@ class Measure;
class Score : public Ms::PluginAPI::ScoreElement {
Q_OBJECT
// Q_PROPERTY(QString composer READ composer)
// Q_PROPERTY(int duration READ duration)
/** The list of the excerpts (linked parts) */
/** Composer of the score, as taken from the score properties (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(QString composer READ composer)
/** Duration of score in seconds (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(int duration READ duration)
/** List of the excerpts (linked parts) (read only) */
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Excerpt> excerpts READ excerpts)
/** The first measure of the score */
Q_PROPERTY(Ms::PluginAPI::Measure* firstMeasure READ firstMeasure)
// Q_PROPERTY(Ms::Measure* firstMeasureMM READ firstMeasureMM)
// Q_PROPERTY(int harmonyCount READ harmonyCount)
// Q_PROPERTY(bool hasHarmonies READ hasHarmonies)
// Q_PROPERTY(bool hasLyrics READ hasLyrics)
// Q_PROPERTY(int keysig READ keysig)
/** The last measure of the score */
Q_PROPERTY(Ms::PluginAPI::Measure* lastMeasure READ lastMeasure)
// Q_PROPERTY(Ms::Measure* lastMeasureMM READ lastMeasureMM)
/** The last score segment */
Q_PROPERTY(Ms::PluginAPI::Segment* lastSegment READ lastSegment) // TODO: make it function? Was property in 2.X, but firstSegment is a function...
// Q_PROPERTY(int lyricCount READ lyricCount)
// // Q_PROPERTY(QString name READ name WRITE setName)
/** Number of measures */
/** First measure of the score (read only) */
Q_PROPERTY(Ms::PluginAPI::Measure* firstMeasure READ firstMeasure)
/** First multimeasure rest measure of the score (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(Ms::PluginAPI::Measure* firstMeasureMM READ firstMeasureMM)
/** Number of harmony items (chord symbols) in the score (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(int harmonyCount READ harmonyCount)
/** Whether score has harmonies (chord symbols) (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(bool hasHarmonies READ hasHarmonies)
/** Whether score has lyrics (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(bool hasLyrics READ hasLyrics)
/// Key signature at the start of the score, in number of accidentals,
/// negative for flats, postitive for sharps (read only).\n \since MuseScore 3.1
Q_PROPERTY(int keysig READ keysig)
/** Last measure of the score (read only) */
Q_PROPERTY(Ms::PluginAPI::Measure* lastMeasure READ lastMeasure)
/** Last multimeasure rest measure of the score (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(Ms::PluginAPI::Measure* lastMeasureMM READ lastMeasureMM)
/** Last score segment (read only) */
Q_PROPERTY(Ms::PluginAPI::Segment* lastSegment READ lastSegment) // TODO: make it function? Was property in 2.X, but firstSegment is a function...
/** Number of lyrics items (syllables) in the score (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(int lyricCount READ lyricCount)
/** Name of the score, without path leading to it and extension.\n \since MuseScore 3.1 */
Q_PROPERTY(QString name READ name WRITE setName)
/** Number of measures (read only) */
Q_PROPERTY(int nmeasures READ nmeasures)
/** Number of pages */
/** Number of pages (read only) */
Q_PROPERTY(int npages READ npages)
/** Number of staves */
/** Number of staves (read only) */
Q_PROPERTY(int nstaves READ nstaves)
/** Number of tracks */
/** Number of tracks (#nstaves * 4) (read only) */
Q_PROPERTY(int ntracks READ ntracks)
// Q_PROPERTY(Ms::PageFormat* pageFormat READ pageFormat WRITE undoChangePageFormat)
// Q_PROPERTY(Ms::PageFormat* pageFormat READ pageFormat WRITE undoChangePageFormat)
/** The list of parts */
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Part> parts READ parts)
// Q_PROPERTY(QString poet READ poet)
// Q_PROPERTY(QString subtitle READ subtitle)
// Q_PROPERTY(QString title READ title)
/** Lyricist of score, as taken from the score properties.\n \since MuseScore 3.1 */
Q_PROPERTY(QString poet READ poet)
// Q_PROPERTY(QString subtitle READ subtitle)
/** Title of score, as taken from the score properties' workTitle (read only).\n \since MuseScore 3.1 */
Q_PROPERTY(QString title READ title)
/** MuseScore version the score has been last saved with (includes autosave) (read only) */
Q_PROPERTY(QString mscoreVersion READ mscoreVersion)
/** MuseScore revision the score has been last saved with (includes autosave) (read only) */
Q_PROPERTY(QString mscoreRevision READ mscoreRevision)
public:
@ -73,6 +88,16 @@ class Score : public Ms::PluginAPI::ScoreElement {
Ms::Score* score() { return toScore(e); }
const Ms::Score* score() const { return toScore(e); }
QString composer() { return score()->metaTag("composer"); }
int duration() { return score()->duration(); }
int harmonyCount() { return score()->harmonyCount(); }
bool hasHarmonies() { return score()->hasHarmonies(); }
bool hasLyrics() { return score()->hasLyrics(); }
int keysig() { return score()->keysig(); }
int lyricCount() { return score()->lyricCount(); }
QString poet() { return score()->metaTag("lyricist"); } // not the meanwhile obsolete "poet"
QString title() { return score()->metaTag("workTitle"); }
/// \endcond
/// Returns as a string the metatag named \p tag
@ -80,12 +105,12 @@ class Score : public Ms::PluginAPI::ScoreElement {
/// Sets the metatag named \p tag to \p val
Q_INVOKABLE void setMetaTag(const QString& tag, const QString& val) { score()->setMetaTag(tag, val); }
// //@ appends to the score a named part as last part
// Q_INVOKABLE void appendPart(const QString&);
// //@ appends to the score a named part as last part
// Q_INVOKABLE void appendPart(const QString&);
/// Appends a number of measures to this score.
Q_INVOKABLE void appendMeasures(int n) { score()->appendMeasures(n); }
Q_INVOKABLE void addText(const QString& type, const QString& text);
/// Creates and returns a cursor to be used to navigate the score
/// Creates and returns a cursor to be used to navigate in the score
Q_INVOKABLE Ms::PluginAPI::Cursor* newCursor();
Q_INVOKABLE Ms::PluginAPI::Segment* firstSegment(); // TODO: segment type
@ -93,16 +118,18 @@ class Score : public Ms::PluginAPI::ScoreElement {
Segment* lastSegment();
Measure* firstMeasure();
Measure* firstMeasureMM();
Measure* lastMeasure();
/// \endcond
Measure* lastMeasureMM();
// // QString name() const { return score()->name(); }
// // void setName(const QString& name) { score()->setName(name); } // TODO: MasterScore
QString name() const { return score()->masterScore()->title(); }
void setName(const QString& name) { score()->masterScore()->setName(name); } // TODO: MasterScore
/// \endcond
Q_INVOKABLE QString extractLyrics() { return score()->extractLyrics(); }
// //@ ??
// Q_INVOKABLE void updateRepeatList(bool expandRepeats) { score()->updateRepeatList(); } // TODO: needed?
// //@ ??
// Q_INVOKABLE void updateRepeatList(bool expandRepeats) { score()->updateRepeatList(); } // TODO: needed?
/// \cond MS_INTERNAL
int nmeasures() const { return score()->nmeasures(); }

View file

@ -82,11 +82,11 @@ class FileIO : public QObject {
Q_INVOKABLE QString homePath() {QDir dir; return dir.homePath();}
/** Returns a path suitable for a temporary file */
Q_INVOKABLE QString tempPath() {QDir dir; return dir.tempPath();}
/** Returns the file modification time */
/** Returns the file's last modification time */
Q_INVOKABLE int modifiedTime();
/// \cond MS_INTERNAL
QString source() { return mSource; };
QString source() { return mSource; }
public slots:
void setSource(const QString& source) { mSource = source; }

View file

@ -121,9 +121,6 @@ MuseScore {
onRun: {
console.log("hello colornotes");
if (typeof curScore === 'undefined')
Qt.quit();
applyToNotesInSelection(colorNote)
Qt.quit();

View file

@ -1,10 +1,10 @@
import QtQuick 2.0
import MuseScore 1.0
import MuseScore 3.0
MuseScore {
menuPath: "Plugins.helloQml"
version: "2.0"
version: "3.0"
description: qsTr("This demo plugin shows some basic tasks.")
pluginType: "dialog"
@ -12,9 +12,6 @@ MuseScore {
height: 75
onRun: {
console.log(qsTr("hello world"));
if (typeof curScore === 'undefined')
Qt.quit();
var score = curScore
console.log(curScore)
console.log(score.name)

View file

@ -115,9 +115,6 @@ MuseScore {
}
onRun: {
if (typeof curScore === 'undefined')
Qt.quit();
var cursor = curScore.newCursor();
var startStaff;
var endStaff;

View file

@ -26,7 +26,7 @@ import MuseScore 3.0
MuseScore {
menuPath: "Plugins.run"
version: "2.0"
version: "3.0"
description: "This demo plugin runs an external command. Probably this will only work on Linux."
requiresScore: false

View file

@ -1,10 +1,10 @@
import QtQuick 2.0
import MuseScore 1.0
import MuseScore 3.0
MuseScore {
menuPath: "Plugins.scorelist"
version: "2.0"
version: "3.0"
description: "This test plugin iterates through the score list."
pluginType: "dialog"

View file

@ -1,8 +1,8 @@
import QtQuick 2.0
import MuseScore 1.0
import MuseScore 3.0
MuseScore {
version: "1.0"
version: "3.0"
description: "Demo plugin to demonstrate the use of a ScoreView"
menuPath: "Plugins.ScoreView"
pluginType: "dialog"