Merge pull request #4631 from heuchi/283179-plugin-api

fix #283179: Add some objects and properties to plugin api
This commit is contained in:
anatoly-os 2019-03-04 13:38:31 +02:00 committed by GitHub
commit ec099095cb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 207 additions and 8 deletions

View file

@ -53,14 +53,17 @@ if (SCRIPT_INTERFACE)
plugin/pluginCreator.h plugin/pluginManager.h plugin/qmledit.h
plugin/qmlplugin.h plugin/qmlpluginengine.h
plugin/api/qmlpluginapi.h plugin/api/cursor.h plugin/api/scoreelement.h plugin/api/elements.h
plugin/api/part.h
plugin/api/score.h
plugin/api/fraction.h
plugin/api/excerpt.h
plugin/api/enums.cpp
plugin/mscorePlugins.cpp plugin/pluginCreator.cpp plugin/pluginManager.cpp plugin/qmledit.cpp
plugin/qmlplugin.cpp plugin/qmlpluginengine.cpp
plugin/api/qmlpluginapi.cpp plugin/api/cursor.cpp plugin/api/scoreelement.cpp plugin/api/elements.cpp
plugin/api/score.cpp
plugin/api/excerpt.cpp
)
set (SCRIPT_UI

View file

@ -21,6 +21,7 @@
#include "libmscore/note.h"
#include "libmscore/notedot.h"
#include "libmscore/segment.h"
#include "libmscore/accidental.h"
namespace Ms {
namespace PluginAPI {
@ -304,8 +305,8 @@ class Element : public Ms::PluginAPI::ScoreElement {
class Note : public Element {
Q_OBJECT
// Q_PROPERTY(Ms::Accidental* accidental READ accidental)
// Q_PROPERTY(int accidentalType READ qmlAccidentalType WRITE qmlSetAccidentalType)
Q_PROPERTY(Ms::PluginAPI::Element* accidental READ accidental)
Q_PROPERTY(Ms::AccidentalType accidentalType READ accidentalType WRITE setAccidentalType)
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Element> dots READ dots)
// Q_PROPERTY(int dotsCount READ qmlDotsCount)
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Element> elements READ elements)
@ -345,6 +346,11 @@ class Note : public Element {
QQmlListProperty<Element> dots() { return wrapContainerProperty<Element>(this, note()->dots()); }
QQmlListProperty<Element> elements() { return wrapContainerProperty<Element>(this, note()->el()); }
Element* accidental() { return wrap<Element>(note()->accidental()); }
Ms::AccidentalType accidentalType() { return note()->accidentalType(); }
void setAccidentalType(Ms::AccidentalType t) { note()->setAccidentalType(t); }
};
//---------------------------------------------------------
@ -378,7 +384,7 @@ class Chord : public Element {
class Segment : public Element {
Q_OBJECT
// TODO
// Q_PROPERTY(QQmlListProperty<Ms::Element> annotations READ qmlAnnotations)
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Element> annotations READ annotations)
Q_PROPERTY(Ms::PluginAPI::Segment* next READ nextInScore)
Q_PROPERTY(Ms::PluginAPI::Segment* nextInMeasure READ nextInMeasure)
Q_PROPERTY(Ms::PluginAPI::Segment* prev READ prevInScore)
@ -404,6 +410,7 @@ class Segment : public Element {
Segment* nextInMeasure() { return wrap<Segment>(segment()->next()); }
Segment* prevInScore() { return wrap<Segment>(segment()->prev1()); }
Segment* prevInMeasure() { return wrap<Segment>(segment()->prev()); }
QQmlListProperty<Element> annotations() { return wrapContainerProperty<Element>(this, segment()->annotations()); }
};
//---------------------------------------------------------

View file

@ -0,0 +1,39 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2019 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#include "excerpt.h"
#include "score.h"
#include "libmscore/score.h"
namespace Ms {
namespace PluginAPI {
//---------------------------------------------------------
// Excerpt::partScore
//---------------------------------------------------------
Score* Excerpt::partScore()
{
return wrap<Score>(e->partScore(), Ownership::SCORE);
}
//---------------------------------------------------------
// wrap
//---------------------------------------------------------
Excerpt* excerptWrap(Ms::Excerpt* e)
{
return excerptWrap<Excerpt>(e);
}
}
}

View file

@ -0,0 +1,96 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2019 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __PLUGIN_API_EXCERPT_H__
#define __PLUGIN_API_EXCERPT_H__
#include "libmscore/excerpt.h"
namespace Ms {
namespace PluginAPI {
class Score;
//---------------------------------------------------------
// Excerpt
// Wrapper class for Excerpt
//
// This is based on the wrapper in scoreelement.h, which
// we cannot use here, because Ms::Excerpt is not derived
// from Ms::ScoreElement.
// Since a plugin should never need to create an Excerpt
// instance by itself, we don't care for Ownership here.
//---------------------------------------------------------
class Excerpt : public QObject {
Q_OBJECT
Q_PROPERTY(Ms::PluginAPI::Score* partScore READ partScore)
Q_PROPERTY(QString title READ title)
protected:
Ms::Excerpt* const e;
public:
Excerpt(Ms::Excerpt* _e = nullptr)
: QObject(), e(_e) {}
Excerpt(const Excerpt&) = delete;
Excerpt& operator=(const Excerpt&) = delete;
virtual ~Excerpt() {};
Score* partScore();
QString title() { return e->title(); }
};
//---------------------------------------------------------
// wrap
//---------------------------------------------------------
template <class Wrapper, class T>
Wrapper* excerptWrap(T* t)
{
Wrapper* w = t ? new Wrapper(t) : nullptr;
// All wrapper objects should belong to JavaScript code.
QQmlEngine::setObjectOwnership(w, QQmlEngine::JavaScriptOwnership);
return w;
}
extern Excerpt* excerptWrap(Ms::Excerpt* e);
//---------------------------------------------------------
// qml access to containers of Excerpt
//
// QmlExcerptsListAccess provides a convenience interface
// for QQmlListProperty providing read-only access to
// plugins for Excerpts containers.
//
// based on QmlListAccess in scoreelement.h
//---------------------------------------------------------
template <typename T, class Container>
class QmlExcerptsListAccess : public QQmlListProperty<T> {
public:
QmlExcerptsListAccess(QObject* obj, Container& container)
: QQmlListProperty<T>(obj, &container, &count, &at) {};
static int count(QQmlListProperty<T>* l) { return int(static_cast<Container*>(l->data)->size()); }
static T* at(QQmlListProperty<T>* l, int i) { return excerptWrap<T>(static_cast<Container*>(l->data)->at(i)); }
};
template<typename T, class Container>
QmlExcerptsListAccess<T, Container> wrapExcerptsContainerProperty(QObject* obj, Container& c)
{
return QmlExcerptsListAccess<T, Container>(obj, c);
}
} // namespace PluginAPI
} // namespace Ms
#endif

43
mscore/plugin/api/part.h Normal file
View file

@ -0,0 +1,43 @@
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2019 Werner Schweer and others
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License version 2
// as published by the Free Software Foundation and appearing in
// the file LICENCE.GPL
//=============================================================================
#ifndef __PLUGIN_API_PART_H__
#define __PLUGIN_API_PART_H__
#include "scoreelement.h"
#include "libmscore/part.h"
namespace Ms {
namespace PluginAPI {
//---------------------------------------------------------
// Part
//---------------------------------------------------------
class Part : public Ms::PluginAPI::ScoreElement {
Q_OBJECT
Q_PROPERTY(int startTrack READ startTrack)
Q_PROPERTY(int endTrack READ endTrack)
public:
Part(Ms::Part* p = nullptr, Ownership o = Ownership::SCORE)
: ScoreElement(p, o) {}
Ms::Part* part() { return toPart(e); }
const Ms::Part* part() const { return toPart(e); }
int startTrack() const { return part()->startTrack(); }
int endTrack() const { return part()->endTrack(); }
};
} // namespace PluginAPI
} // namespace Ms
#endif

View file

@ -15,6 +15,7 @@
#include "elements.h"
#include "fraction.h"
#include "score.h"
#include "part.h"
#ifndef TESTROOT
#include "shortcut.h"
#endif
@ -125,7 +126,7 @@ bool PluginAPI::writeScore(Score* s, const QString& name, const QString& ext)
Score* PluginAPI::readScore(const QString& name, bool noninteractive)
{
Ms::Score* score = msc()->openScore(name, true);
Ms::Score* score = msc()->openScore(name, !noninteractive);
if (score) {
if (noninteractive)
score->setCreated(false);
@ -306,12 +307,13 @@ void PluginAPI::registerQmlTypes()
qmlRegisterType<Note>();
qmlRegisterType<Segment>();
qmlRegisterType<Measure>();
qmlRegisterType<Part>();
qmlRegisterType<Excerpt>();
#if 0
qmlRegisterType<NoteHead> ("MuseScore", 1, 0, "NoteHead");
qmlRegisterType<Accidental> ("MuseScore", 1, 0, "Accidental");
qmlRegisterType<Rest> ("MuseScore", 1, 0, "Rest");
qmlRegisterType<StaffText> ("MuseScore", 1, 0, "StaffText");
qmlRegisterType<Part> ("MuseScore", 1, 0, "Part");
qmlRegisterType<Staff> ("MuseScore", 1, 0, "Staff");
qmlRegisterType<Harmony> ("MuseScore", 1, 0, "Harmony");
qmlRegisterType<TimeSig> ("MuseScore", 1, 0, "TimeSig");
@ -328,7 +330,6 @@ void PluginAPI::registerQmlTypes()
qmlRegisterType<Stem> ("MuseScore", 1, 0, "Stem");
qmlRegisterType<StemSlash> ("MuseScore", 1, 0, "StemSlash");
qmlRegisterType<Beam> ("MuseScore", 1, 0, "Beam");
qmlRegisterType<Excerpt> ("MuseScore", 1, 0, "Excerpt");
qmlRegisterType<BarLine> ("MuseScore", 1, 0, "BarLine");

View file

@ -14,6 +14,8 @@
#define __PLUGIN_API_SCORE_H__
#include "scoreelement.h"
#include "part.h"
#include "excerpt.h"
#include "libmscore/score.h"
namespace Ms {
@ -31,7 +33,7 @@ class Score : public Ms::PluginAPI::ScoreElement {
Q_OBJECT
// Q_PROPERTY(QString composer READ composer)
// Q_PROPERTY(int duration READ duration)
// Q_PROPERTY(QQmlListProperty<Ms::Excerpt> excerpts READ qmlExcerpts)
Q_PROPERTY(QQmlListProperty<Ms::PluginAPI::Excerpt> excerpts READ excerpts)
Q_PROPERTY(Ms::PluginAPI::Measure* firstMeasure READ firstMeasure)
// Q_PROPERTY(Ms::Measure* firstMeasureMM READ firstMeasureMM)
// Q_PROPERTY(int harmonyCount READ harmonyCount)
@ -49,6 +51,7 @@ class Score : public Ms::PluginAPI::ScoreElement {
Q_PROPERTY(int ntracks READ ntracks)
// Q_PROPERTY(Ms::PageFormat* pageFormat READ pageFormat WRITE undoChangePageFormat)
// Q_PROPERTY(QQmlListProperty<Ms::Part> parts READ qmlParts)
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)
@ -100,6 +103,9 @@ class Score : public Ms::PluginAPI::ScoreElement {
QString mscoreVersion() { return score()->mscoreVersion(); }
QString mscoreRevision() { return QString::number(score()->mscoreRevision(), /* base */ 16); }
QQmlListProperty<Part> parts() { return wrapContainerProperty<Part>(this, score()->parts()); }
QQmlListProperty<Excerpt> excerpts() { return wrapExcerptsContainerProperty<Excerpt>(this, score()->excerpts()); }
};
} // namespace PluginAPI
} // namespace Ms

View file

@ -102,6 +102,8 @@ ScoreElement* wrap(Ms::ScoreElement* se, Ownership own)
switch(se->type()) {
case ElementType::SCORE:
return wrap<Score>(toScore(se), own);
case ElementType::PART:
return wrap<Part>(toPart(se), own);
default:
break;
}

View file

@ -96,7 +96,7 @@ template <typename T, class Container>
class QmlListAccess : public QQmlListProperty<T> {
public:
QmlListAccess(QObject* obj, Container& container)
: QQmlListProperty<T>(obj, &container, &count, &at) {};
: QQmlListProperty<T>(obj, const_cast<void*>(static_cast<const void*>(&container)), &count, &at) {};
static int count(QQmlListProperty<T>* l) { return int(static_cast<Container*>(l->data)->size()); }
static T* at(QQmlListProperty<T>* l, int i) { return wrap<T>(static_cast<Container*>(l->data)->at(i), Ownership::SCORE); }

View file

@ -100,6 +100,8 @@ set (SOURCE_LIB
${PROJECT_SOURCE_DIR}/mscore/plugin/api/scoreelement.cpp
${PROJECT_SOURCE_DIR}/mscore/plugin/api/elements.cpp
${PROJECT_SOURCE_DIR}/mscore/plugin/api/score.cpp
${PROJECT_SOURCE_DIR}/mscore/plugin/api/part.h
${PROJECT_SOURCE_DIR}/mscore/plugin/api/excerpt.cpp
${PROJECT_SOURCE_DIR}/mscore/preferences.cpp
${PROJECT_SOURCE_DIR}/mscore/shortcut.cpp
${PROJECT_SOURCE_DIR}/mscore/stringutils.cpp