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:
Maurizio M. Gavioli 2014-07-06 01:56:30 +02:00
parent 7fc68113a1
commit d11f1b118b
13 changed files with 110 additions and 41 deletions

View file

@ -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);
}
//---------------------------------------------------------

View file

@ -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

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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();

View file

@ -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

View file

@ -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));

View file

@ -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;
}

View file

@ -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)

View file

@ -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();