MuseScore/libmscore/measure.h

272 lines
10 KiB
C
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
// Copyright (C) 2002-2011 Werner Schweer
//
// 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 __MEASURE_H__
#define __MEASURE_H__
/**
\file
2016-12-28 16:23:10 +01:00
Definition of class Measure.
2012-05-26 14:26:10 +02:00
*/
#include "measurebase.h"
#include "fraction.h"
#include "segmentlist.h"
2013-05-13 18:49:17 +02:00
namespace Ms {
2016-11-19 11:51:21 +01:00
class XmlWriter;
2012-05-26 14:26:10 +02:00
class Beam;
class Tuplet;
class Staff;
class Chord;
class Text;
class ChordRest;
class Score;
class MuseScoreView;
class System;
class Note;
class Spacer;
class TieMap;
class AccidentalState;
class Spanner;
class Part;
class RepeatMeasure;
2012-05-26 14:26:10 +02:00
2016-12-12 14:55:35 +01:00
class MStaff;
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// MeasureNumberMode
//---------------------------------------------------------
enum class MeasureNumberMode : char {
AUTO, // show measure number depending on style
SHOW, // always show measure number
HIDE // dont show measure number
};
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2012-07-11 21:29:42 +02:00
// @@ Measure
2012-07-25 11:49:34 +02:00
/// one measure in a system
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.
2014-07-06 01:56:30 +02:00
//
// @P firstSegment Segment the first segment of the measure (read-only)
// @P lastSegment Segment the last segment of the measure (read-only)
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
class Measure final : public MeasureBase {
2016-02-06 22:03:43 +01:00
std::vector<MStaff*> _mstaves;
2012-05-26 14:26:10 +02:00
SegmentList _segments;
2016-01-04 14:48:58 +01:00
Measure* _mmRest; // multi measure rest which replaces a measure range
qreal _userStretch;
2016-02-04 11:27:47 +01:00
Fraction _timesig;
Fraction _len; ///< actual length of measure
2016-01-04 14:48:58 +01:00
int _mmRestCount; // > 0 if this is a multi measure rest
// 0 if this is the start of a mm rest (_mmRest != 0)
// < 0 if this measure is covered by a mm rest
int _playbackCount; // temp. value used in RepeatList
// counts how many times this measure was already played
2012-05-26 14:26:10 +02:00
2016-01-04 14:48:58 +01:00
int _repeatCount; ///< end repeat marker und repeat count
2012-05-26 14:26:10 +02:00
MeasureNumberMode _noMode;
2016-01-04 14:48:58 +01:00
bool _breakMultiMeasureRest;
2012-05-26 14:26:10 +02:00
void push_back(Segment* e);
void push_front(Segment* e);
void fillGap(const Fraction& pos, const Fraction& len, int track, const Fraction& stretch);
2016-11-07 09:59:06 +01:00
void computeMinWidth(Segment* s, qreal x, bool isSystemHeader);
2012-05-26 14:26:10 +02:00
public:
Measure(Score* = 0);
2012-05-26 14:26:10 +02:00
Measure(const Measure&);
~Measure();
virtual Measure* clone() const override { return new Measure(*this); }
2017-01-18 14:16:33 +01:00
virtual ElementType type() const override { return ElementType::MEASURE; }
virtual void setScore(Score* s) override;
2013-07-05 11:23:52 +02:00
Measure* cloneMeasure(Score*, TieMap*);
2012-05-26 14:26:10 +02:00
2013-01-17 12:56:14 +01:00
void read(XmlReader&, int idx);
2013-01-11 18:10:18 +01:00
void read(XmlReader& d) { read(d, 0); }
2016-11-19 11:51:21 +01:00
virtual void write(XmlWriter& xml) const override { Element::write(xml); }
void write(XmlWriter&, int, bool writeSystemElements, bool forceTimeSig) const;
2016-11-19 11:51:21 +01:00
void writeBox(XmlWriter&) const;
2013-01-11 18:10:18 +01:00
void readBox(XmlReader&);
virtual bool isEditable() const override { return false; }
void checkMeasure(int idx);
2012-05-26 14:26:10 +02:00
virtual void add(Element*) override;
virtual void remove(Element*) override;
virtual void change(Element* o, Element* n) override;
virtual void spatiumChanged(qreal oldValue, qreal newValue) override;
2012-05-26 14:26:10 +02:00
2016-12-12 12:02:18 +01:00
System* system() const { return (System*)parent(); }
2016-12-12 14:55:35 +01:00
bool hasVoices(int staffIdx) const;
void setHasVoices(int staffIdx, bool v);
StaffLines* staffLines(int staffIdx);
Spacer* vspacerDown(int staffIdx) const;
Spacer* vspacerUp(int staffIdx) const;
void setStaffVisible(int staffIdx, bool visible);
void setStaffSlashStyle(int staffIdx, bool slashStyle);
bool corrupted(int staffIdx) const;
void setCorrupted(int staffIdx, bool val);
void setNoText(int staffIdx, Text*);
Text* noText(int staffIdx) const;
2017-09-19 15:20:06 +02:00
const Shape& staffShape(int staffIdx) const;
2016-12-12 14:55:35 +01:00
Shape& staffShape(int staffIdx);
void createStaves(int);
MeasureNumberMode measureNumberMode() const { return _noMode; }
void setMeasureNumberMode(MeasureNumberMode v) { _noMode = v; }
2012-05-26 14:26:10 +02:00
Fraction timesig() const { return _timesig; }
void setTimesig(const Fraction& f) { _timesig = f; }
Fraction len() const { return _len; }
Fraction stretchedLen(Staff*) const;
void setLen(const Fraction& f) { _len = f; }
2016-12-18 14:31:13 +01:00
virtual int ticks() const override; // actual length of measure in ticks
2016-08-06 11:36:51 +02:00
bool isIrregular() const { return _timesig != _len; }
2012-05-26 14:26:10 +02:00
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.
2014-07-06 01:56:30 +02:00
int size() const { return _segments.size(); }
Ms::Segment* first() const { return _segments.first(); }
2017-03-08 13:12:26 +01:00
Segment* first(SegmentType t) const { return _segments.first(t); }
2012-05-26 14:26:10 +02:00
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.
2014-07-06 01:56:30 +02:00
Ms::Segment* last() const { return _segments.last(); }
2016-02-11 18:20:16 +01:00
SegmentList& segments() { return _segments; }
const SegmentList& segments() const { return _segments; }
2012-05-26 14:26:10 +02:00
2014-05-17 18:40:05 +02:00
qreal userStretch() const;
void setUserStretch(qreal v) { _userStretch = v; }
2012-05-26 14:26:10 +02:00
2016-01-04 14:48:58 +01:00
void stretchMeasure(qreal stretch);
2012-05-26 14:26:10 +02:00
void layout2();
2013-06-24 13:46:21 +02:00
Chord* findChord(int tick, int track);
2012-05-26 14:26:10 +02:00
ChordRest* findChordRest(int tick, int track);
int snap(int tick, const QPointF p) const;
int snapNote(int tick, const QPointF p, int staff) const;
void insertStaff(Staff*, int staff);
void insertMStaff(MStaff* staff, int idx);
void removeMStaff(MStaff* staff, int idx);
virtual void moveTicks(int diff);
void cmdRemoveStaves(int s, int e);
void cmdAddStaves(int s, int e, bool createRest);
void removeStaves(int s, int e);
void insertStaves(int s, int e);
qreal tick2pos(int) const;
2017-03-08 13:12:26 +01:00
Segment* tick2segment(int tick, SegmentType st = SegmentType::ChordRest);
2012-05-26 14:26:10 +02:00
void sortStaves(QList<int>& dst);
2017-03-31 13:03:15 +02:00
virtual bool acceptDrop(EditData&) const override;
virtual Element* drop(EditData&) override;
2012-05-26 14:26:10 +02:00
int repeatCount() const { return _repeatCount; }
void setRepeatCount(int val) { _repeatCount = val; }
2017-03-08 13:12:26 +01:00
Segment* undoGetSegment(SegmentType st, int tick); // deprecated
Segment* getSegment(SegmentType st, int tick); // deprecated
Segment* findSegment(SegmentType st, int tick) const; // deprecated
2016-10-20 11:32:07 +02:00
2017-03-08 13:12:26 +01:00
Segment* undoGetSegmentR(SegmentType st, int rtick);
Segment* getSegmentR(SegmentType st, int rtick);
Segment* findSegmentR(SegmentType st, int rtick) const;
// preferred:
2017-03-08 13:12:26 +01:00
Segment* undoGetSegment(SegmentType st, const Fraction& f) { return undoGetSegmentR(st, f.ticks()); }
Segment* getSegment(SegmentType st, const Fraction& f) { return getSegmentR(st, f.ticks()); }
2017-03-08 13:12:26 +01:00
Segment* findFirst(SegmentType st, int rtick) const;
2012-05-26 14:26:10 +02:00
2016-01-04 14:48:58 +01:00
qreal createEndBarLines(bool);
2016-10-18 15:41:00 +02:00
void barLinesSetSpan(Segment*);
void setEndBarLineType(BarLineType val, int track, bool visible = true, QColor color = QColor());
2012-05-26 14:26:10 +02:00
RepeatMeasure* cmdInsertRepeatMeasure(int staffIdx);
virtual void scanElements(void* data, void (*func)(void*, Element*), bool all=true) override;
2012-05-26 14:26:10 +02:00
void createVoice(int track);
void adjustToLen(Fraction, bool appendRestsIfNecessary = true);
2014-07-17 09:32:30 +02:00
2012-08-08 20:46:29 +02:00
AccidentalVal findAccidental(Note*) const;
AccidentalVal findAccidental(Segment* s, int staffIdx, int line, bool &error) const;
2014-08-29 10:35:17 +02:00
void exchangeVoice(int voice1, int voice2, int staffIdx);
2012-05-26 14:26:10 +02:00
void checkMultiVoices(int staffIdx);
bool hasVoice(int track) const;
2015-08-04 19:53:54 +02:00
bool isMeasureRest(int staffIdx) const;
bool isFullMeasureRest() const;
bool isRepeatMeasure(Staff* staff) const;
2012-05-26 14:26:10 +02:00
bool visible(int staffIdx) const;
bool slashStyle(int staffIdx) const;
bool isFinalMeasureOfSection() const;
bool isAnacrusis() const;
2012-05-26 14:26:10 +02:00
2016-01-04 14:48:58 +01:00
bool breakMultiMeasureRest() const { return _breakMultiMeasureRest; }
2012-05-26 14:26:10 +02:00
void setBreakMultiMeasureRest(bool val) { _breakMultiMeasureRest = val; }
2016-02-06 22:03:43 +01:00
bool empty() const;
bool isOnlyRests(int track) const;
bool isOnlyDeletedRests(int track) const;
2012-05-26 14:26:10 +02:00
int playbackCount() const { return _playbackCount; }
void setPlaybackCount(int val) { _playbackCount = val; }
QRectF staffabbox(int staffIdx) const;
virtual QVariant getProperty(P_ID propertyId) const override;
virtual bool setProperty(P_ID propertyId, const QVariant&) override;
virtual QVariant propertyDefault(P_ID) const override;
2012-05-26 14:26:10 +02:00
bool hasMMRest() const { return _mmRest != 0; }
2013-09-27 18:43:25 +02:00
bool isMMRest() const { return _mmRestCount > 0; }
Measure* mmRest() const { return _mmRest; }
const Measure* mmRest1() const;
void setMMRest(Measure* m) { _mmRest = m; }
int mmRestCount() const { return _mmRestCount; } // number of measures _mmRest spans
void setMMRestCount(int n) { _mmRestCount = n; }
2013-10-30 14:21:08 +01:00
Measure* mmRestFirst() const;
Measure* mmRestLast() const;
Element* nextElementStaff(int staff);
Element* prevElementStaff(int staff);
2016-02-04 17:06:32 +01:00
virtual QString accessibleInfo() const override;
2016-01-04 14:48:58 +01:00
2016-10-18 15:41:00 +02:00
void addSystemHeader(bool firstSystem);
void addSystemTrailer(Measure* nm);
void removeSystemHeader();
void removeSystemTrailer();
2016-04-18 09:46:30 +02:00
const BarLine* endBarLine() const;
2016-04-18 09:46:30 +02:00
BarLineType endBarLineType() const;
bool endBarLineVisible() const;
virtual void triggerLayout() const override;
2016-10-18 15:41:00 +02:00
qreal basicStretch() const;
qreal basicWidth() const;
virtual void computeMinWidth();
void checkHeader();
void checkTrailer();
2016-10-31 10:55:11 +01:00
void setStretchedWidth(qreal);
2016-12-12 14:55:35 +01:00
void layoutStaffLines();
};
2013-05-13 18:49:17 +02:00
} // namespace Ms
2012-05-26 14:26:10 +02:00
#endif