Fixes the following Q_INVOKABLE methods returning a QObject* by turning them into a property:
- Measure: -- firstSegment -- lastSegment - MeasureBase: -- nextMeasure -- nextMeasureMM (new) -- prevMeasure -- prevMeasureMM (new) - Score: -- firstMeasure -- firstMeasureMM (new) -- (for firstSegment(), see special cases below) -- lastMeasure -- lastMeasureMM (new) -- lastSegment - Segment: -- next (renamed from `next1`) -- nextInMeasure (renamed from `next`) -- prev (renamed from `prev1`) -- prevInMeasure (renamed from prev) Special cases: - Cursor: The prototype of the `Q_INVOKABLE Ms::Note* Cursor::addNote(int pitch)` was wrong: corrected in `Q_INVOKABLE void Cursor::addNote(int pitch)`. - QmlPlugin: `Q_INVOKABLE Score* QmlPlugin::readScore()` and `Q_INVOKABLE Score* QmlPlugin::newScore()` has been kept, as they are intended to be called from QML; code has been added to ensure the C++ ownership of the returned object. - Score: `Q_INVOKABLE Segment* Score::firstSegment(Segment::Type segType)` is kept (as it needs a parameters), but code is added to ensure C++ ownership of the returned Segment*. - Segment: `Ms::Element* Segment::element(int track)` has been made NOT Q_INVOKABLE; a variant `Q_INVOKABLE Ms::Element* elementAt(int track)` has been added specifically for QML with code to ensure the C++ ownership of the returned Element* (this was the cause for the crash of the Walk plug-in). - FiguredBass: `Q_INVOKABLE Ms::FiguredBassItem* FiguredBass::addItem()` has been removed; plugin interface for FiguredBass needs to be redesigned anyway. The few occurrences in the supplied plug-ins of the methods whose names did change have been updated.
This commit is contained in:
parent
7fc68113a1
commit
d11f1b118b
13 changed files with 110 additions and 41 deletions
|
@ -155,10 +155,10 @@ void Cursor::add(Element* s)
|
|||
// addNote
|
||||
//---------------------------------------------------------
|
||||
|
||||
Note* Cursor::addNote(int pitch)
|
||||
void Cursor::addNote(int pitch)
|
||||
{
|
||||
NoteVal nval(pitch);
|
||||
return _score->addPitch(nval, false);
|
||||
_score->addPitch(nval, false);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
|
|
@ -96,7 +96,7 @@ class Cursor : public QObject {
|
|||
Q_INVOKABLE bool nextMeasure();
|
||||
Q_INVOKABLE void add(Ms::Element*);
|
||||
|
||||
Q_INVOKABLE Ms::Note* addNote(int pitch);
|
||||
Q_INVOKABLE void addNote(int pitch);
|
||||
|
||||
//@ set duration
|
||||
//@ z: numerator
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include "sym.h"
|
||||
#include "xml.h"
|
||||
|
||||
// trying to do without it
|
||||
//#include <QQmlEngine>
|
||||
|
||||
namespace Ms {
|
||||
|
||||
// the array of configured fonts
|
||||
|
@ -1324,15 +1327,17 @@ QVariant FiguredBass::propertyDefault(P_ID id) const
|
|||
//---------------------------------------------------------
|
||||
// TEMPORARY HACK!!!
|
||||
//---------------------------------------------------------
|
||||
|
||||
/*
|
||||
FiguredBassItem * FiguredBass::addItem()
|
||||
{
|
||||
int line = items.size();
|
||||
FiguredBassItem* fib = new FiguredBassItem(score(), line);
|
||||
// tell QML not to garbage collect this item
|
||||
QQmlEngine::setObjectOwnership(fib, QQmlEngine::CppOwnership);
|
||||
items.push_back(fib);
|
||||
return fib;
|
||||
}
|
||||
|
||||
*/
|
||||
//---------------------------------------------------------
|
||||
// STATIC FUNCTION
|
||||
// adding a new FiguredBass to a Segment;
|
||||
|
|
|
@ -294,7 +294,7 @@ class FiguredBass : public Text {
|
|||
void writeMusicXML(Xml& xml, bool doFigure, bool doExtend) const;
|
||||
|
||||
//DEBUG
|
||||
Q_INVOKABLE Ms::FiguredBassItem* addItem();
|
||||
//Q_INVOKABLE Ms::FiguredBassItem* addItem();
|
||||
|
||||
// getters / setters / properties
|
||||
// void qmlItemsAppend(QDeclarativeListProperty<FiguredBassItem> *list, FiguredBassItem * pItem)
|
||||
|
|
|
@ -94,11 +94,17 @@ enum class MeasureNumberMode : char {
|
|||
//---------------------------------------------------------
|
||||
// @@ Measure
|
||||
/// one measure in a system
|
||||
//
|
||||
// @P firstSegment Ms::Segment the first segment of the measure (read-only)
|
||||
// @P lastSegment Ms::Segment the last segment of the measure (read-only)
|
||||
//---------------------------------------------------------
|
||||
|
||||
class Measure : public MeasureBase {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(Ms::Segment* fistSegment READ last)
|
||||
Q_PROPERTY(Ms::Segment* lastSegment READ first)
|
||||
|
||||
SegmentList _segments;
|
||||
|
||||
Fraction _timesig;
|
||||
|
@ -192,16 +198,16 @@ class Measure : public MeasureBase {
|
|||
// actual length of measure in ticks
|
||||
virtual int ticks() const override;
|
||||
|
||||
int size() const { return _segments.size(); }
|
||||
Q_INVOKABLE Ms::Segment* first() const { return _segments.first(); }
|
||||
Segment* first(Segment::Type t) const { return _segments.first(t); }
|
||||
int size() const { return _segments.size(); }
|
||||
Ms::Segment* first() const { return _segments.first(); }
|
||||
Segment* first(Segment::Type t) const { return _segments.first(t); }
|
||||
|
||||
Q_INVOKABLE Ms::Segment* last() const { return _segments.last(); }
|
||||
Ms::Segment* last() const { return _segments.last(); }
|
||||
void remove(Segment* s);
|
||||
SegmentList* segments() { return &_segments; }
|
||||
SegmentList* segments() { return &_segments; }
|
||||
|
||||
qreal userStretch() const;
|
||||
void setUserStretch(qreal v) { _userStretch = v; }
|
||||
void setUserStretch(qreal v) { _userStretch = v; }
|
||||
|
||||
void layoutX(qreal stretch);
|
||||
void layout(qreal width);
|
||||
|
|
|
@ -31,15 +31,23 @@ class Measure;
|
|||
// @@ MeasureBase
|
||||
/// Virtual base class for Measure, HBox and VBox
|
||||
//
|
||||
// @P lineBreak bool true if a system break is positioned on this measure
|
||||
// @P pageBreak bool true if a page break is positioned on this measure
|
||||
// @P lineBreak bool true if a system break is positioned on this measure
|
||||
// @P nextMeasure Ms::Measure the next Measure (read-only)
|
||||
// @P nextMeasureMM Ms::Measure the next multi-measure rest Measure (read-only)
|
||||
// @P pageBreak bool true if a page break is positioned on this measure
|
||||
// @P prevMeasure Ms::Measure the previous Measure (read-only)
|
||||
// @P prevMeasureMM Ms::Measure the previous multi-measure rest Measure (read-only)
|
||||
//---------------------------------------------------------
|
||||
|
||||
class MeasureBase : public Element {
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(bool lineBreak READ lineBreak WRITE undoSetLineBreak)
|
||||
Q_PROPERTY(bool pageBreak READ pageBreak WRITE undoSetPageBreak)
|
||||
Q_PROPERTY(bool lineBreak READ lineBreak WRITE undoSetLineBreak)
|
||||
Q_PROPERTY(Ms::Measure* nextMeasure READ nextMeasure)
|
||||
Q_PROPERTY(Ms::Measure* nextMeasureMM READ nextMeasureMM)
|
||||
Q_PROPERTY(bool pageBreak READ pageBreak WRITE undoSetPageBreak)
|
||||
Q_PROPERTY(Ms::Measure* prevMeasure READ prevMeasure)
|
||||
Q_PROPERTY(Ms::Measure* prevMeasureMM READ prevMeasureMM)
|
||||
|
||||
MeasureBase* _next;
|
||||
MeasureBase* _prev;
|
||||
|
@ -67,8 +75,8 @@ class MeasureBase : public Element {
|
|||
MeasureBase* prev() const { return _prev; }
|
||||
void setPrev(MeasureBase* e) { _prev = e; }
|
||||
|
||||
Q_INVOKABLE Ms::Measure* nextMeasure() const;
|
||||
Q_INVOKABLE Ms::Measure* prevMeasure() const;
|
||||
Ms::Measure* nextMeasure() const;
|
||||
Ms::Measure* prevMeasure() const;
|
||||
Ms::Measure* nextMeasureMM() const;
|
||||
Ms::Measure* prevMeasureMM() const;
|
||||
|
||||
|
|
|
@ -1659,6 +1659,12 @@ Measure* Score::lastMeasureMM() const
|
|||
Segment* Score::firstSegment(Segment::Type segType) const
|
||||
{
|
||||
Measure* m = firstMeasure();
|
||||
Segment* seg = m ? m->first(segType) : 0;
|
||||
#ifdef SCRIPT_INTERFACE
|
||||
// if called from QML/JS, tell QML engine not to garbage collect this object
|
||||
if (seg)
|
||||
QQmlEngine::setObjectOwnership(seg, QQmlEngine::CppOwnership);
|
||||
#endif
|
||||
return m ? m->first(segType) : 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -233,18 +233,28 @@ enum class PasteStatus : char {
|
|||
|
||||
//---------------------------------------------------------
|
||||
// @@ Score
|
||||
// @P name QString name of the score
|
||||
// @P nstaves int number of staves (read only)
|
||||
// @P ntracks int number of tracks (staves * 4) (read only)
|
||||
// @P npages int number of pages (read only)
|
||||
// @P firstMeasure Ms::Measure the first measure of the score (read only)
|
||||
// @P firstMeasureMM Ms::Measure the first multi-measure rest measure of the score (read only)
|
||||
// @P lastMeasure Ms::Measure the last measure of the score (read only)
|
||||
// @P lastMeasureMM Ms::Measure the last multi-measure rest measure of the score (read only)
|
||||
// @P lastSegment Ms::Segment the last score segment (read-only)
|
||||
// @P name QString name of the score
|
||||
// @P npages int number of pages (read only)
|
||||
// @P nstaves int number of staves (read only)
|
||||
// @P ntracks int number of tracks (staves * 4) (read only)
|
||||
//---------------------------------------------------------
|
||||
|
||||
class Score : public QObject {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
Q_PROPERTY(int nstaves READ nstaves)
|
||||
Q_PROPERTY(int ntracks READ ntracks)
|
||||
Q_PROPERTY(int npages READ npages)
|
||||
Q_PROPERTY(Ms::Measure* firstMeasure READ firstMeasure)
|
||||
Q_PROPERTY(Ms::Measure* firstMeasureMM READ firstMeasure)
|
||||
Q_PROPERTY(Ms::Measure* lastMeasure READ firstMeasure)
|
||||
Q_PROPERTY(Ms::Measure* lastMeasureMM READ firstMeasure)
|
||||
Q_PROPERTY(Ms::Segment* lastSegment READ lastSegment)
|
||||
Q_PROPERTY(QString name READ name WRITE setName)
|
||||
Q_PROPERTY(int npages READ npages)
|
||||
Q_PROPERTY(int nstaves READ nstaves)
|
||||
Q_PROPERTY(int ntracks READ ntracks)
|
||||
|
||||
public:
|
||||
enum class FileError : char {
|
||||
|
@ -792,16 +802,16 @@ class Score : public QObject {
|
|||
MeasureBase* first() const;
|
||||
MeasureBase* firstMM() const;
|
||||
MeasureBase* last() const;
|
||||
Q_INVOKABLE Ms::Measure* firstMeasure() const;
|
||||
Ms::Measure* firstMeasure() const;
|
||||
Ms::Measure* firstMeasureMM() const;
|
||||
Q_INVOKABLE Ms::Measure* lastMeasure() const;
|
||||
Ms::Measure* lastMeasure() const;
|
||||
Ms::Measure* lastMeasureMM() const;
|
||||
// int measureIdx(MeasureBase*) const;
|
||||
MeasureBase* measure(int idx) const;
|
||||
|
||||
Q_INVOKABLE Ms::Segment* firstSegment(Segment::Type s = Segment::Type::All) const;
|
||||
Ms::Segment* firstSegmentMM(Segment::Type s = Segment::Type::All) const;
|
||||
Q_INVOKABLE Ms::Segment* lastSegment() const;
|
||||
Ms::Segment* lastSegment() const;
|
||||
|
||||
void connectTies();
|
||||
|
||||
|
|
|
@ -937,5 +937,20 @@ void Segment::clearAnnotations()
|
|||
_annotations.clear();
|
||||
}
|
||||
|
||||
}
|
||||
//---------------------------------------------------------
|
||||
// elementAt
|
||||
// A variant of the element(int) function,
|
||||
// specifically intended to be called from QML plugins
|
||||
//---------------------------------------------------------
|
||||
|
||||
Ms::Element* Segment::elementAt(int track) const {
|
||||
Element* e = _elist.value(track);
|
||||
#ifdef SCRIPT_INTERFACE
|
||||
// if called from QML/JS, tell QML engine not to garbage collect this object
|
||||
if (e)
|
||||
QQmlEngine::setObjectOwnership(e, QQmlEngine::CppOwnership);
|
||||
#endif
|
||||
return e;
|
||||
}
|
||||
|
||||
} // namespace Ms
|
||||
|
|
|
@ -36,7 +36,11 @@ class System;
|
|||
/// A segment holds all vertical aligned staff elements.
|
||||
/// Segments are typed and contain only Elements of the same type.
|
||||
//
|
||||
// @P segmentType Ms::Segment::Type (Invalid, Clef, KeySig, Ambitus, TimeSig, StartRepeatBarLine, BarLine, ChordRest, Breath, EndBarLine TimeSigAnnounce, KeySigAnnounce, All)
|
||||
// @P next Ms::Segment the next segment in the whole score; null at last score segment (read-only)
|
||||
// @P nextInMeasure Ms::Segment the next segment in measure; null at last measure segment (read-only)
|
||||
// @P prev Ms::Segment the previous segment in the whole score; null at first score segment (read-only)
|
||||
// @P prevInMeasure Ms::Segment the previous segment in measure; null at first measure segment (read-only)
|
||||
// @P segmentType Ms::Segment::Type (Invalid, Clef, KeySig, Ambitus, TimeSig, StartRepeatBarLine, BarLine, ChordRest, Breath, EndBarLine TimeSigAnnounce, KeySigAnnounce, All)
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -51,7 +55,11 @@ class System;
|
|||
|
||||
class Segment : public Element {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(Ms::Segment::Type segmentType READ segmentType WRITE setSegmentType)
|
||||
Q_PROPERTY(Ms::Segment* next READ next1)
|
||||
Q_PROPERTY(Ms::Segment* nextInMeasure READ next)
|
||||
Q_PROPERTY(Ms::Segment* prev READ prev1)
|
||||
Q_PROPERTY(Ms::Segment* prevInMeasure READ prev)
|
||||
Q_PROPERTY(Ms::Segment::Type segmentType READ segmentType WRITE setSegmentType)
|
||||
Q_ENUMS(Type)
|
||||
|
||||
public:
|
||||
|
@ -103,19 +111,19 @@ public:
|
|||
|
||||
virtual void setScore(Score*);
|
||||
|
||||
Q_INVOKABLE Ms::Segment* next() const { return _next; }
|
||||
Ms::Segment* next() const { return _next; }
|
||||
Segment* next(Type) const;
|
||||
|
||||
void setNext(Segment* e) { _next = e; }
|
||||
Q_INVOKABLE Ms::Segment* prev() const { return _prev; }
|
||||
Ms::Segment* prev() const { return _prev; }
|
||||
Segment* prev(Type) const;
|
||||
void setPrev(Segment* e) { _prev = e; }
|
||||
|
||||
Q_INVOKABLE Ms::Segment* next1() const;
|
||||
Ms::Segment* next1() const;
|
||||
Ms::Segment* next1MM() const;
|
||||
Segment* next1(Type) const;
|
||||
Segment* next1MM(Type) const;
|
||||
Q_INVOKABLE Ms::Segment* prev1() const;
|
||||
Ms::Segment* prev1() const;
|
||||
Ms::Segment* prev1MM() const;
|
||||
Segment* prev1(Type) const;
|
||||
Segment* prev1MM(Type) const;
|
||||
|
@ -124,7 +132,9 @@ public:
|
|||
|
||||
ChordRest* nextChordRest(int track, bool backwards = false) const;
|
||||
|
||||
Q_INVOKABLE Ms::Element* element(int track) const { return _elist.value(track); }
|
||||
Ms::Element* element(int track) const { return _elist.value(track); }
|
||||
// a variant of the above function, specifically designed to be called from QML
|
||||
Q_INVOKABLE Ms::Element* elementAt(int track) const;
|
||||
ChordRest* cr(int track) const {
|
||||
Q_ASSERT(_segmentType == Type::ChordRest);
|
||||
return (ChordRest*)(_elist.value(track));
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "musescoreCore.h"
|
||||
#include "libmscore/score.h"
|
||||
|
||||
#include <QQmlEngine>
|
||||
|
||||
namespace Ms {
|
||||
|
||||
extern MuseScoreCore* mscoreCore;
|
||||
|
@ -68,7 +70,11 @@ bool QmlPlugin::writeScore(Score* s, const QString& name, const QString& ext)
|
|||
|
||||
Score* QmlPlugin::readScore(const QString& name)
|
||||
{
|
||||
return msc->openScore(name);
|
||||
Score * score = msc->openScore(name);
|
||||
// tell QML not to garbage collect this score
|
||||
if (score)
|
||||
QQmlEngine::setObjectOwnership(score, QQmlEngine::CppOwnership);
|
||||
return score;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
@ -81,6 +87,7 @@ Ms::Element* QmlPlugin::newElement(int t)
|
|||
if (score == 0)
|
||||
return 0;
|
||||
Element* e = Element::create(Element::Type(t), score);
|
||||
// tell QML not to garbage collect this score
|
||||
Ms::MScore::qml()->setObjectOwnership(e, QQmlEngine::CppOwnership);
|
||||
return e;
|
||||
}
|
||||
|
@ -103,6 +110,8 @@ Score* QmlPlugin::newScore(const QString& name, const QString& part, int measure
|
|||
int view = msc->appendScore(score);
|
||||
msc->setCurrentView(0, view);
|
||||
qApp->processEvents();
|
||||
// tell QML not to garbage collect this score
|
||||
QQmlEngine::setObjectOwnership(score, QQmlEngine::CppOwnership);
|
||||
score->startCmd();
|
||||
return score;
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ MuseScore {
|
|||
var segment = m.first()
|
||||
while (segment) {
|
||||
var element
|
||||
element = segment.element(0)
|
||||
element = segment.elementAt(0)
|
||||
if (element && element.type == Element.CHORD) {
|
||||
console.log(qsTr(" element"))
|
||||
console.log(element.beamMode)
|
||||
|
|
|
@ -28,12 +28,12 @@ MuseScore {
|
|||
var segment = curScore.firstSegment();
|
||||
while (segment) {
|
||||
console.log("segment: " + segment + " type " + segment.segmentType);
|
||||
var element = segment.element(track);
|
||||
var element = segment.elementAt(track);
|
||||
if (element) {
|
||||
var type = element.type;
|
||||
console.log(type);
|
||||
}
|
||||
segment = segment.next1();
|
||||
segment = segment.next;
|
||||
}
|
||||
}
|
||||
Qt.quit();
|
||||
|
|
Loading…
Reference in a new issue