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
|
|
|
|
//=============================================================================
|
|
|
|
|
|
|
|
#include "mscore.h"
|
|
|
|
#include "staff.h"
|
|
|
|
#include "part.h"
|
|
|
|
#include "clef.h"
|
|
|
|
#include "xml.h"
|
|
|
|
#include "score.h"
|
|
|
|
#include "bracket.h"
|
|
|
|
#include "keysig.h"
|
|
|
|
#include "segment.h"
|
|
|
|
#include "style.h"
|
|
|
|
#include "measure.h"
|
2013-12-05 21:37:28 +01:00
|
|
|
#include "stringdata.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
#include "stafftype.h"
|
|
|
|
#include "undo.h"
|
|
|
|
#include "cleflist.h"
|
|
|
|
#include "timesig.h"
|
|
|
|
#include "instrtemplate.h"
|
2012-10-20 20:32:40 +02:00
|
|
|
#include "barline.h"
|
2013-07-16 09:03:47 +02:00
|
|
|
#include "ottava.h"
|
2015-02-20 11:56:13 +01:00
|
|
|
#include "harmony.h"
|
2017-03-31 13:03:15 +02:00
|
|
|
#include "bracketItem.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2015-06-26 11:55:44 +02:00
|
|
|
// #define DEBUG_CLEFS
|
|
|
|
|
|
|
|
#ifdef DEBUG_CLEFS
|
|
|
|
#define DUMP_CLEFS(s) dumpClefs(s)
|
|
|
|
#else
|
|
|
|
#define DUMP_CLEFS(s)
|
|
|
|
#endif
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// idx
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::idx() const
|
|
|
|
{
|
2016-09-28 21:13:05 +02:00
|
|
|
return score()->staves().indexOf((Staff*)this, 0);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// fillBrackets
|
|
|
|
// make sure index idx is valid
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::fillBrackets(int idx)
|
|
|
|
{
|
|
|
|
for (int i = _brackets.size(); i <= idx; ++i) {
|
|
|
|
BracketItem* bi = new BracketItem(score());
|
|
|
|
bi->setStaff(this);
|
|
|
|
_brackets.append(bi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// cleanBrackets
|
|
|
|
// remove NO_BRACKET entries from the end of list
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::cleanBrackets()
|
|
|
|
{
|
|
|
|
while (!_brackets.empty() && (_brackets.last()->bracketType() == BracketType::NO_BRACKET))
|
|
|
|
delete _brackets.takeLast();
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// bracket
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
BracketType Staff::bracketType(int idx) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
if (idx < _brackets.size())
|
2017-03-31 13:03:15 +02:00
|
|
|
return _brackets[idx]->bracketType();
|
2014-05-26 22:25:34 +02:00
|
|
|
return BracketType::NO_BRACKET;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// bracketSpan
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::bracketSpan(int idx) const
|
|
|
|
{
|
|
|
|
if (idx < _brackets.size())
|
2017-03-31 13:03:15 +02:00
|
|
|
return _brackets[idx]->bracketSpan();
|
2012-05-26 14:26:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setBracket
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
void Staff::setBracketType(int idx, BracketType val)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2017-03-31 13:03:15 +02:00
|
|
|
fillBrackets(idx);
|
|
|
|
_brackets[idx]->setBracketType(val);
|
|
|
|
cleanBrackets();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2016-12-29 19:46:40 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// swapBracket
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-01-05 11:23:47 +01:00
|
|
|
void Staff::swapBracket(int oldIdx, int newIdx)
|
2016-12-29 19:46:40 +01:00
|
|
|
{
|
2017-03-31 13:03:15 +02:00
|
|
|
int idx = qMax(oldIdx, newIdx);
|
|
|
|
fillBrackets(idx);
|
2016-12-29 19:46:40 +01:00
|
|
|
_brackets.swap(oldIdx, newIdx);
|
2017-03-31 13:03:15 +02:00
|
|
|
cleanBrackets();
|
2016-12-29 19:46:40 +01:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setBracketSpan
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::setBracketSpan(int idx, int val)
|
|
|
|
{
|
2012-10-12 15:36:57 +02:00
|
|
|
Q_ASSERT(idx >= 0);
|
|
|
|
Q_ASSERT(val >= 0);
|
2017-03-31 13:03:15 +02:00
|
|
|
fillBrackets(idx);
|
|
|
|
_brackets[idx]->setBracketSpan(val);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// addBracket
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
void Staff::addBracket(BracketItem* b)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2017-03-31 13:03:15 +02:00
|
|
|
b->setStaff(this);
|
|
|
|
if (!_brackets.empty() && _brackets[0]->bracketType() == BracketType::NO_BRACKET)
|
2012-05-26 14:26:10 +02:00
|
|
|
_brackets[0] = b;
|
|
|
|
else {
|
|
|
|
//
|
|
|
|
// create new bracket level
|
|
|
|
//
|
2017-03-31 13:03:15 +02:00
|
|
|
for (Staff* s : score()->staves()) {
|
2012-05-26 14:26:10 +02:00
|
|
|
if (s == this)
|
|
|
|
s->_brackets.append(b);
|
2017-03-31 13:03:15 +02:00
|
|
|
else {
|
|
|
|
BracketItem* bi = new BracketItem(score());
|
|
|
|
bi->setStaff(this);
|
|
|
|
s->_brackets.append(bi);
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-02 13:20:19 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// innerBracket
|
|
|
|
// Return type inner bracket.
|
|
|
|
// The bracket type determines the staff distance.
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
BracketType Staff::innerBracket() const
|
|
|
|
{
|
|
|
|
int staffIdx = idx();
|
|
|
|
|
|
|
|
BracketType t = BracketType::NO_BRACKET;
|
|
|
|
int level = 1000;
|
|
|
|
for (int i = 0; i < score()->nstaves(); ++i) {
|
|
|
|
Staff* staff = score()->staff(i);
|
|
|
|
for (int k = 0; k < staff->brackets().size(); ++k) {
|
2017-03-31 13:03:15 +02:00
|
|
|
const BracketItem* bi = staff->brackets().at(k);
|
|
|
|
if (bi->bracketType() != BracketType::NO_BRACKET) {
|
|
|
|
if (i < staffIdx && ((i + bi->bracketSpan()) > staffIdx) && k < level) {
|
|
|
|
t = bi->bracketType();
|
2016-03-02 13:20:19 +01:00
|
|
|
level = k;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return t;
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// cleanupBrackets
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::cleanupBrackets()
|
|
|
|
{
|
|
|
|
int index = idx();
|
2016-03-10 10:41:31 +01:00
|
|
|
int n = score()->nstaves();
|
2012-05-26 14:26:10 +02:00
|
|
|
for (int i = 0; i < _brackets.size(); ++i) {
|
2017-03-31 13:03:15 +02:00
|
|
|
if (_brackets[i]->bracketType() == BracketType::NO_BRACKET)
|
2013-06-05 15:47:34 +02:00
|
|
|
continue;
|
2017-03-31 13:03:15 +02:00
|
|
|
int span = _brackets[i]->bracketSpan();
|
2013-06-05 15:47:34 +02:00
|
|
|
if (span > (n - index)) {
|
|
|
|
span = n - index;
|
2017-03-31 13:03:15 +02:00
|
|
|
_brackets[i]->setBracketSpan(span);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for (int i = 0; i < _brackets.size(); ++i) {
|
2017-03-31 13:03:15 +02:00
|
|
|
if (_brackets[i]->bracketType() == BracketType::NO_BRACKET)
|
2013-06-05 15:47:34 +02:00
|
|
|
continue;
|
2017-03-31 13:03:15 +02:00
|
|
|
int span = _brackets[i]->bracketSpan();
|
|
|
|
if (span <= 1) {
|
|
|
|
_brackets[i] = new BracketItem(score());
|
|
|
|
_brackets[i]->setStaff(this);
|
|
|
|
}
|
2013-06-05 15:47:34 +02:00
|
|
|
else {
|
|
|
|
// delete all other brackets with same span
|
|
|
|
for (int k = i + 1; k < _brackets.size(); ++k) {
|
2017-03-31 13:03:15 +02:00
|
|
|
if (span == _brackets[k]->bracketSpan()) {
|
|
|
|
_brackets[k] = new BracketItem(score());
|
|
|
|
_brackets[k]->setStaff(this);
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// bracketLevels
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::bracketLevels() const
|
|
|
|
{
|
|
|
|
int columns = 0;
|
|
|
|
for (auto bi : _brackets)
|
|
|
|
columns = qMax(columns, bi->column());
|
|
|
|
return columns;
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// partName
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QString Staff::partName() const
|
|
|
|
{
|
|
|
|
return _part->partName();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// ~Staff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Staff::~Staff()
|
|
|
|
{
|
|
|
|
if (_linkedStaves) {
|
|
|
|
_linkedStaves->remove(this);
|
2016-02-06 22:03:43 +01:00
|
|
|
if (_linkedStaves->empty())
|
2012-05-26 14:26:10 +02:00
|
|
|
delete _linkedStaves;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2014-08-16 11:21:56 +02:00
|
|
|
// Staff::clefType
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-08-16 11:21:56 +02:00
|
|
|
ClefTypeList Staff::clefType(int tick) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2014-08-14 14:29:35 +02:00
|
|
|
ClefTypeList ct = clefs.clef(tick);
|
|
|
|
if (ct._concertClef == ClefType::INVALID) {
|
2016-12-13 13:16:17 +01:00
|
|
|
switch(staffType(tick)->group()) {
|
2014-08-16 11:21:56 +02:00
|
|
|
case StaffGroup::TAB:
|
2016-09-18 18:37:42 +02:00
|
|
|
{
|
|
|
|
ClefType sct = ClefType(score()->styleI(StyleIdx::tabClef));
|
2016-12-13 13:16:17 +01:00
|
|
|
ct = staffType(tick)->lines() <= 4 ? ClefTypeList(sct == ClefType::TAB ? ClefType::TAB4 : ClefType::TAB4_SERIF) : ClefTypeList(sct == ClefType::TAB ? ClefType::TAB : ClefType::TAB_SERIF);
|
2016-09-18 18:37:42 +02:00
|
|
|
}
|
2014-08-14 14:29:35 +02:00
|
|
|
break;
|
|
|
|
case StaffGroup::STANDARD:
|
2014-08-16 11:21:56 +02:00
|
|
|
ct = defaultClefType();
|
2014-08-14 14:29:35 +02:00
|
|
|
break;
|
|
|
|
case StaffGroup::PERCUSSION:
|
2014-08-16 11:21:56 +02:00
|
|
|
ct = ClefTypeList(ClefType::PERC);
|
2014-08-14 14:29:35 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return ct;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// Staff::clef
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ClefType Staff::clef(int tick) const
|
|
|
|
{
|
2014-08-16 11:21:56 +02:00
|
|
|
ClefTypeList c = clefType(tick);
|
2014-05-26 15:31:36 +02:00
|
|
|
return score()->styleB(StyleIdx::concertPitch) ? c._concertClef : c._transposingClef;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2016-10-25 17:30:55 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// Staff::nextClefTick
|
|
|
|
//
|
|
|
|
// return the tick of next clef after tick
|
|
|
|
// return last tick of score if not found
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::nextClefTick(int tick) const
|
|
|
|
{
|
|
|
|
int t = clefs.nextClefTick(tick);
|
2017-02-13 17:06:30 +01:00
|
|
|
return t != -1 ? t : score()->endTick();
|
2016-10-25 17:30:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2015-02-14 15:10:35 +01:00
|
|
|
#ifndef NDEBUG
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// dumpClef
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::dumpClefs(const char* title) const
|
|
|
|
{
|
2016-12-28 19:08:54 +01:00
|
|
|
qDebug("(%zd): %s", clefs.size(), title);
|
2015-02-14 15:10:35 +01:00
|
|
|
for (auto& i : clefs) {
|
2015-02-14 16:24:29 +01:00
|
|
|
qDebug(" %d: %d %d", i.first, int(i.second._concertClef), int(i.second._transposingClef));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// dumpKeys
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::dumpKeys(const char* title) const
|
|
|
|
{
|
2016-12-28 19:08:54 +01:00
|
|
|
qDebug("(%zd): %s", _keys.size(), title);
|
2015-02-14 16:24:29 +01:00
|
|
|
for (auto& i : _keys) {
|
|
|
|
qDebug(" %d: %d", i.first, int(i.second.key()));
|
2015-02-14 15:10:35 +01:00
|
|
|
}
|
|
|
|
}
|
2015-02-16 12:12:23 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// dumpTimeSigs
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::dumpTimeSigs(const char* title) const
|
|
|
|
{
|
2016-12-28 19:08:54 +01:00
|
|
|
qDebug("size (%zd) staffIdx %d: %s", timesigs.size(), idx(), title);
|
2015-02-16 12:12:23 +01:00
|
|
|
for (auto& i : timesigs) {
|
|
|
|
qDebug(" %d: %d/%d", i.first, i.second->sig().numerator(), i.second->sig().denominator());
|
|
|
|
}
|
|
|
|
}
|
2015-02-14 15:10:35 +01:00
|
|
|
#endif
|
|
|
|
|
2013-09-05 16:37:49 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setClef
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-07-25 17:13:27 +02:00
|
|
|
void Staff::setClef(Clef* clef)
|
2013-09-05 16:37:49 +02:00
|
|
|
{
|
2016-03-18 09:29:16 +01:00
|
|
|
// qDebug("Staff::setClef generated %d", clef->generated());
|
2014-08-05 14:10:22 +02:00
|
|
|
if (clef->generated())
|
|
|
|
return;
|
2014-07-25 17:13:27 +02:00
|
|
|
int tick = clef->segment()->tick();
|
|
|
|
for (Segment* s = clef->segment()->next(); s && s->tick() == tick; s = s->next()) {
|
2017-03-08 13:12:26 +01:00
|
|
|
if (s->segmentType() == SegmentType::Clef && s->element(clef->track())) {
|
2014-07-25 17:13:27 +02:00
|
|
|
// adding this clef has no effect on the clefs list
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
clefs.setClef(clef->segment()->tick(), clef->clefTypeList());
|
2015-06-26 11:55:44 +02:00
|
|
|
DUMP_CLEFS("setClef");
|
2013-09-05 16:37:49 +02:00
|
|
|
}
|
|
|
|
|
2014-05-08 17:59:24 +02:00
|
|
|
//---------------------------------------------------------
|
2014-07-25 17:13:27 +02:00
|
|
|
// removeClef
|
2014-05-08 17:59:24 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-07-25 17:13:27 +02:00
|
|
|
void Staff::removeClef(Clef* clef)
|
2013-09-05 16:37:49 +02:00
|
|
|
{
|
2016-03-18 09:29:16 +01:00
|
|
|
// qDebug("Staff::removeClef generated %d", clef->generated());
|
2014-08-05 14:10:22 +02:00
|
|
|
if (clef->generated())
|
|
|
|
return;
|
2014-07-25 17:13:27 +02:00
|
|
|
int tick = clef->segment()->tick();
|
|
|
|
for (Segment* s = clef->segment()->next(); s && s->tick() == tick; s = s->next()) {
|
2017-03-08 13:12:26 +01:00
|
|
|
if (s->segmentType() == SegmentType::Clef && s->element(clef->track())) {
|
2014-07-25 17:13:27 +02:00
|
|
|
// removal of this clef has no effect on the clefs list
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
clefs.erase(clef->segment()->tick());
|
|
|
|
for (Segment* s = clef->segment()->prev(); s && s->tick() == tick; s = s->prev()) {
|
2017-03-08 13:12:26 +01:00
|
|
|
if (s->segmentType() == SegmentType::Clef
|
2015-02-14 15:10:35 +01:00
|
|
|
&& s->element(clef->track())
|
|
|
|
&& !s->element(clef->track())->generated()) {
|
2014-07-25 17:13:27 +02:00
|
|
|
// a previous clef at the same tick position gets valid
|
2017-12-20 16:49:30 +01:00
|
|
|
clefs.setClef(tick, toClef(s->element(clef->track()))->clefTypeList());
|
2014-07-25 17:13:27 +02:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2015-06-26 11:55:44 +02:00
|
|
|
DUMP_CLEFS("removeClef");
|
2013-09-05 16:37:49 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2014-05-08 17:59:24 +02:00
|
|
|
// timeStretch
|
2013-09-05 16:37:49 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-05-08 17:59:24 +02:00
|
|
|
Fraction Staff::timeStretch(int tick) const
|
2013-09-05 16:37:49 +02:00
|
|
|
{
|
2014-05-08 17:59:24 +02:00
|
|
|
TimeSig* timesig = timeSig(tick);
|
2016-11-02 08:55:54 +01:00
|
|
|
return timesig ? timesig->stretch() : Fraction(1,1);
|
2013-09-05 16:37:49 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// timeSig
|
2012-06-27 12:53:40 +02:00
|
|
|
// lookup time signature before or at tick
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
TimeSig* Staff::timeSig(int tick) const
|
|
|
|
{
|
2013-05-06 14:20:31 +02:00
|
|
|
auto i = timesigs.upper_bound(tick);
|
|
|
|
if (i != timesigs.begin())
|
|
|
|
--i;
|
2014-11-27 13:04:03 +01:00
|
|
|
else if (tick < i->first)
|
|
|
|
return 0;
|
2013-05-06 14:20:31 +02:00
|
|
|
return (i == timesigs.end()) ? 0 : i->second;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2017-07-07 14:50:24 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// nextTimeSig
|
|
|
|
// lookup time signature at tick or after
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
TimeSig* Staff::nextTimeSig(int tick) const
|
|
|
|
{
|
|
|
|
auto i = timesigs.lower_bound(tick);
|
|
|
|
return (i == timesigs.end()) ? 0 : i->second;
|
|
|
|
}
|
|
|
|
|
2013-04-29 15:31:22 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// group
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
const Groups& Staff::group(int tick) const
|
|
|
|
{
|
|
|
|
TimeSig* ts = timeSig(tick);
|
|
|
|
if (ts) {
|
|
|
|
if (!ts->groups().empty())
|
|
|
|
return ts->groups();
|
2013-05-06 14:20:31 +02:00
|
|
|
return Groups::endings(ts->sig());
|
2013-04-29 15:31:22 +02:00
|
|
|
}
|
|
|
|
Measure* m = score()->tick2measure(tick);
|
2014-05-03 10:10:46 +02:00
|
|
|
return Groups::endings(m ? m->timesig() : Fraction(4,4));
|
2013-04-29 15:31:22 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// addTimeSig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::addTimeSig(TimeSig* timesig)
|
|
|
|
{
|
2017-03-08 13:12:26 +01:00
|
|
|
if (timesig->segment()->segmentType() == SegmentType::TimeSig)
|
2014-07-22 19:28:49 +02:00
|
|
|
timesigs[timesig->segment()->tick()] = timesig;
|
2015-02-16 12:12:23 +01:00
|
|
|
// dumpTimeSigs("after addTimeSig");
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// removeTimeSig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::removeTimeSig(TimeSig* timesig)
|
|
|
|
{
|
2017-03-08 13:12:26 +01:00
|
|
|
if (timesig->segment()->segmentType() == SegmentType::TimeSig)
|
2014-07-22 19:28:49 +02:00
|
|
|
timesigs.erase(timesig->segment()->tick());
|
2015-02-16 12:12:23 +01:00
|
|
|
// dumpTimeSigs("after removeTimeSig");
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2014-11-27 13:04:03 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// clearTimeSig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::clearTimeSig()
|
|
|
|
{
|
|
|
|
timesigs.clear();
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
2015-06-13 17:57:57 +02:00
|
|
|
// Staff::keySigEvent
|
2013-05-08 11:21:59 +02:00
|
|
|
//
|
|
|
|
// locates the key sig currently in effect at tick
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-12-08 18:02:17 +01:00
|
|
|
KeySigEvent Staff::keySigEvent(int tick) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2014-06-03 15:28:10 +02:00
|
|
|
return _keys.key(tick);
|
|
|
|
}
|
|
|
|
|
2014-06-04 10:20:14 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setKey
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-12-08 18:02:17 +01:00
|
|
|
void Staff::setKey(int tick, KeySigEvent k)
|
2014-06-04 10:20:14 +02:00
|
|
|
{
|
|
|
|
_keys.setKey(tick, k);
|
2015-03-09 18:31:28 +01:00
|
|
|
// dumpKeys("setKey");
|
2014-06-04 10:20:14 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// removeKey
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::removeKey(int tick)
|
|
|
|
{
|
2014-07-17 09:32:30 +02:00
|
|
|
_keys.erase(tick);
|
2015-03-09 18:31:28 +01:00
|
|
|
// dumpKeys("removeKey");
|
2014-06-04 10:20:14 +02:00
|
|
|
}
|
|
|
|
|
2014-06-03 15:28:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// prevkey
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-12-08 18:02:17 +01:00
|
|
|
KeySigEvent Staff::prevKey(int tick) const
|
2014-06-03 15:28:10 +02:00
|
|
|
{
|
|
|
|
return _keys.prevKey(tick);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
2013-05-08 11:21:59 +02:00
|
|
|
// Staff::nextKeyTick
|
|
|
|
//
|
|
|
|
// return the tick at which the key sig after tick is located
|
|
|
|
// return 0, if no such a key sig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::nextKeyTick(int tick) const
|
|
|
|
{
|
2017-02-13 17:06:30 +01:00
|
|
|
int t = _keys.nextKeyTick(tick);
|
|
|
|
return t != -1 ? t : score()->endTick();
|
2014-06-03 15:28:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// Staff::currentKeyTick
|
|
|
|
//
|
|
|
|
// return the tick position of the key currently
|
|
|
|
// in effect at tick
|
|
|
|
// return 0, if no such a key sig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::currentKeyTick(int tick) const
|
|
|
|
{
|
|
|
|
return _keys.currentKeyTick(tick);
|
2013-05-08 11:21:59 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// write
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-11-19 11:51:21 +01:00
|
|
|
void Staff::write(XmlWriter& xml) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-09-28 21:13:05 +02:00
|
|
|
int idx = this->idx();
|
2013-01-24 14:38:35 +01:00
|
|
|
xml.stag(QString("Staff id=\"%1\"").arg(idx + 1));
|
2012-05-26 14:26:10 +02:00
|
|
|
if (linkedStaves()) {
|
2016-03-10 10:41:31 +01:00
|
|
|
Score* s = masterScore();
|
2016-12-18 14:31:13 +01:00
|
|
|
for (Staff* staff : linkedStaves()->staves()) {
|
2012-05-26 14:26:10 +02:00
|
|
|
if ((staff->score() == s) && (staff != this))
|
2016-09-28 21:13:05 +02:00
|
|
|
xml.tag("linkedTo", staff->idx() + 1);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
2014-04-30 10:08:38 +02:00
|
|
|
|
2014-05-05 15:38:40 +02:00
|
|
|
// for copy/paste we need to know the actual transposition
|
2016-11-19 10:31:14 +01:00
|
|
|
if (xml.clipboardmode()) {
|
2015-09-21 02:13:22 +02:00
|
|
|
Interval v = part()->instrument()->transpose(); // TODO: tick?
|
2014-05-05 15:38:40 +02:00
|
|
|
if (v.diatonic)
|
|
|
|
xml.tag("transposeDiatonic", v.diatonic);
|
|
|
|
if (v.chromatic)
|
|
|
|
xml.tag("transposeChromatic", v.chromatic);
|
|
|
|
}
|
|
|
|
|
2016-12-18 14:31:13 +01:00
|
|
|
staffType(0)->write(xml);
|
2014-08-16 11:21:56 +02:00
|
|
|
ClefTypeList ct = _defaultClefType;
|
|
|
|
if (ct._concertClef == ct._transposingClef) {
|
|
|
|
if (ct._concertClef != ClefType::G)
|
|
|
|
xml.tag("defaultClef", ClefInfo::tag(ct._concertClef));
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
xml.tag("defaultConcertClef", ClefInfo::tag(ct._concertClef));
|
|
|
|
xml.tag("defaultTransposingClef", ClefInfo::tag(ct._transposingClef));
|
|
|
|
}
|
2014-04-30 10:08:38 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
if (invisible())
|
|
|
|
xml.tag("invisible", invisible());
|
2015-08-04 19:53:54 +02:00
|
|
|
if (hideWhenEmpty() != HideMode::AUTO)
|
|
|
|
xml.tag("hideWhenEmpty", int(hideWhenEmpty()));
|
|
|
|
if (cutaway())
|
|
|
|
xml.tag("cutaway", cutaway());
|
2014-08-06 16:37:41 +02:00
|
|
|
if (showIfEmpty())
|
|
|
|
xml.tag("showIfSystemEmpty", showIfEmpty());
|
2015-01-05 17:55:06 +01:00
|
|
|
if (_hideSystemBarLine)
|
|
|
|
xml.tag("hideSystemBarLine", _hideSystemBarLine);
|
2014-07-31 18:46:41 +02:00
|
|
|
|
2017-03-31 13:03:15 +02:00
|
|
|
for (const BracketItem* i : _brackets) {
|
|
|
|
BracketType a = i->bracketType();
|
|
|
|
int b = i->bracketSpan();
|
|
|
|
int c = i->column();
|
|
|
|
if (a != BracketType::NO_BRACKET || b > 0)
|
|
|
|
xml.tagE(QString("bracket type=\"%1\" span=\"%2\" col=\"%3\"").arg((int)(a)).arg(b).arg(c));
|
|
|
|
}
|
2013-01-24 14:38:35 +01:00
|
|
|
|
2016-12-28 16:23:10 +01:00
|
|
|
writeProperty(xml, P_ID::STAFF_BARLINE_SPAN);
|
|
|
|
writeProperty(xml, P_ID::STAFF_BARLINE_SPAN_FROM);
|
|
|
|
writeProperty(xml, P_ID::STAFF_BARLINE_SPAN_TO);
|
2016-12-23 12:05:18 +01:00
|
|
|
writeProperty(xml, P_ID::STAFF_USERDIST);
|
2015-02-04 22:12:13 +01:00
|
|
|
writeProperty(xml, P_ID::COLOR);
|
2016-09-16 12:07:37 +02:00
|
|
|
writeProperty(xml, P_ID::PLAYBACK_VOICE1);
|
|
|
|
writeProperty(xml, P_ID::PLAYBACK_VOICE2);
|
|
|
|
writeProperty(xml, P_ID::PLAYBACK_VOICE3);
|
|
|
|
writeProperty(xml, P_ID::PLAYBACK_VOICE4);
|
2012-05-26 14:26:10 +02:00
|
|
|
xml.etag();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// read
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-01-11 18:10:18 +01:00
|
|
|
void Staff::read(XmlReader& e)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2013-01-11 18:10:18 +01:00
|
|
|
while (e.readNextStartElement()) {
|
2016-12-23 12:05:18 +01:00
|
|
|
if (!readProperties(e))
|
|
|
|
e.unknown();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// readProperties
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::readProperties(XmlReader& e)
|
|
|
|
{
|
|
|
|
const QStringRef& tag(e.name());
|
|
|
|
if (tag == "StaffType") {
|
|
|
|
StaffType st;
|
|
|
|
st.read(e);
|
|
|
|
_staffTypeList.setStaffType(0, &st);
|
|
|
|
}
|
|
|
|
else if (tag == "defaultClef") { // sets both default transposing and concert clef
|
|
|
|
QString val(e.readElementText());
|
|
|
|
ClefType ct = Clef::clefType(val);
|
|
|
|
setDefaultClefType(ClefTypeList(ct, ct));
|
|
|
|
}
|
|
|
|
else if (tag == "defaultConcertClef") {
|
|
|
|
QString val(e.readElementText());
|
|
|
|
setDefaultClefType(ClefTypeList(Clef::clefType(val), defaultClefType()._transposingClef));
|
|
|
|
}
|
|
|
|
else if (tag == "defaultTransposingClef") {
|
|
|
|
QString val(e.readElementText());
|
|
|
|
setDefaultClefType(ClefTypeList(defaultClefType()._concertClef, Clef::clefType(val)));
|
|
|
|
}
|
2017-02-13 18:21:12 +01:00
|
|
|
else if (tag == "small") // obsolete
|
|
|
|
setSmall(0, e.readInt());
|
2016-12-23 12:05:18 +01:00
|
|
|
else if (tag == "invisible")
|
|
|
|
setInvisible(e.readInt());
|
|
|
|
else if (tag == "hideWhenEmpty")
|
|
|
|
setHideWhenEmpty(HideMode(e.readInt()));
|
|
|
|
else if (tag == "cutaway")
|
|
|
|
setCutaway(e.readInt());
|
|
|
|
else if (tag == "showIfSystemEmpty")
|
|
|
|
setShowIfEmpty(e.readInt());
|
|
|
|
else if (tag == "hideSystemBarLine")
|
|
|
|
_hideSystemBarLine = e.readInt();
|
|
|
|
else if (tag == "keylist")
|
|
|
|
_keys.read(e, score());
|
|
|
|
else if (tag == "bracket") {
|
2017-03-31 13:03:15 +02:00
|
|
|
BracketItem* b = new BracketItem(score());
|
|
|
|
b->setStaff(this);
|
|
|
|
b->setBracketType(BracketType(e.intAttribute("type", -1)));
|
|
|
|
b->setBracketSpan(e.intAttribute("span", 0));
|
|
|
|
int col = e.intAttribute("col", -1);
|
|
|
|
if (col == -1)
|
|
|
|
col = _brackets.size();
|
|
|
|
b->setColumn(col);
|
2016-12-23 12:05:18 +01:00
|
|
|
_brackets.append(b);
|
|
|
|
e.readNext();
|
|
|
|
}
|
|
|
|
else if (tag == "barLineSpan")
|
2017-05-29 14:59:10 +02:00
|
|
|
_barLineSpan = e.readInt();
|
2016-12-23 12:05:18 +01:00
|
|
|
else if (tag == "barLineSpanFrom")
|
|
|
|
_barLineFrom = e.readInt();
|
|
|
|
else if (tag == "barLineSpanTo")
|
|
|
|
_barLineTo = e.readInt();
|
|
|
|
else if (tag == "distOffset")
|
|
|
|
_userDist = e.readDouble() * score()->spatium();
|
|
|
|
else if (tag == "mag")
|
|
|
|
/*_userMag =*/ e.readDouble(0.1, 10.0);
|
|
|
|
else if (tag == "linkedTo") {
|
|
|
|
int v = e.readInt() - 1;
|
|
|
|
//
|
|
|
|
// if this is an excerpt, link staff to masterScore()
|
|
|
|
//
|
|
|
|
if (!score()->isMaster()) {
|
|
|
|
Staff* st = masterScore()->staff(v);
|
|
|
|
if (st)
|
|
|
|
linkTo(st);
|
2012-05-26 14:26:10 +02:00
|
|
|
else {
|
2016-12-23 12:05:18 +01:00
|
|
|
qDebug("staff %d not found in parent", v);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
2016-12-23 12:05:18 +01:00
|
|
|
else {
|
|
|
|
if (v >= 0 && v < idx())
|
|
|
|
linkTo(score()->staff(v));
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2016-12-23 12:05:18 +01:00
|
|
|
else if (tag == "color")
|
|
|
|
_color = e.readColor();
|
|
|
|
else if (tag == "transposeDiatonic")
|
|
|
|
e.setTransposeDiatonic(e.readInt());
|
|
|
|
else if (tag == "transposeChromatic")
|
|
|
|
e.setTransposeChromatic(e.readInt());
|
|
|
|
else if (tag == "playbackVoice1")
|
|
|
|
setPlaybackVoice(0, e.readInt());
|
|
|
|
else if (tag == "playbackVoice2")
|
|
|
|
setPlaybackVoice(1, e.readInt());
|
|
|
|
else if (tag == "playbackVoice3")
|
|
|
|
setPlaybackVoice(2, e.readInt());
|
|
|
|
else if (tag == "playbackVoice4")
|
|
|
|
setPlaybackVoice(3, e.readInt());
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
return true;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// height
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
qreal Staff::height() const
|
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
int tick = 0; // TODO
|
2016-12-23 12:05:18 +01:00
|
|
|
return (lines(tick) == 1 ? 2 : lines(tick)-1) * spatium(tick) * staffType(tick)->lineDistance().val();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// spatium
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-23 12:05:18 +01:00
|
|
|
qreal Staff::spatium(int tick) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-12-23 12:05:18 +01:00
|
|
|
return score()->spatium() * mag(tick);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// mag
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-23 12:05:18 +01:00
|
|
|
qreal Staff::mag(int tick) const
|
|
|
|
{
|
|
|
|
return (small(tick) ? score()->styleD(StyleIdx::smallStaffMag) : 1.0) * userMag(tick);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// userMag
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
qreal Staff::userMag(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->userMag();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setUserMag
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::setUserMag(int tick, qreal m)
|
|
|
|
{
|
|
|
|
return staffType(tick)->setUserMag(m);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// small
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::small(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->small();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setSmall
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::setSmall(int tick, bool val)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-12-23 12:05:18 +01:00
|
|
|
staffType(tick)->setSmall(val);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2014-07-24 20:09:49 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// swing
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
SwingParameters Staff::swing(int tick) const
|
|
|
|
{
|
|
|
|
SwingParameters sp;
|
2014-12-18 20:41:15 +01:00
|
|
|
int swingUnit = 0;
|
2014-07-24 20:09:49 +02:00
|
|
|
QString unit = score()->styleSt(StyleIdx::swingUnit);
|
|
|
|
int swingRatio = score()->styleI(StyleIdx::swingRatio);
|
2014-08-15 18:32:48 +02:00
|
|
|
if (unit == TDuration(TDuration::DurationType::V_EIGHTH).name()) {
|
2014-07-24 20:09:49 +02:00
|
|
|
swingUnit = MScore::division / 2;
|
|
|
|
}
|
|
|
|
else if (unit == TDuration(TDuration::DurationType::V_16TH).name())
|
|
|
|
swingUnit = MScore::division / 4;
|
|
|
|
else if (unit == TDuration(TDuration::DurationType::V_ZERO).name())
|
|
|
|
swingUnit = 0;
|
|
|
|
sp.swingRatio = swingRatio;
|
|
|
|
sp.swingUnit = swingUnit;
|
2016-02-06 22:03:43 +01:00
|
|
|
if (_swingList.empty())
|
2014-07-24 20:09:49 +02:00
|
|
|
return sp;
|
|
|
|
QMap<int, SwingParameters>::const_iterator i = _swingList.upperBound(tick);
|
|
|
|
if (i == _swingList.begin())
|
|
|
|
return sp;
|
|
|
|
--i;
|
|
|
|
return i.value();
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// channel
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::channel(int tick, int voice) const
|
|
|
|
{
|
2016-02-06 22:03:43 +01:00
|
|
|
if (_channelList[voice].empty())
|
2012-05-26 14:26:10 +02:00
|
|
|
return 0;
|
2014-02-01 22:17:20 +01:00
|
|
|
QMap<int, int>::const_iterator i = _channelList[voice].upperBound(tick);
|
2012-05-26 14:26:10 +02:00
|
|
|
if (i == _channelList[voice].begin())
|
2014-02-01 22:17:20 +01:00
|
|
|
return 0;
|
2012-05-26 14:26:10 +02:00
|
|
|
--i;
|
|
|
|
return i.value();
|
|
|
|
}
|
|
|
|
|
2015-09-01 06:19:20 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// middleLine
|
|
|
|
// returns logical line number of middle staff line
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
int Staff::middleLine(int tick) const
|
2015-09-01 06:19:20 +02:00
|
|
|
{
|
2016-12-23 12:05:18 +01:00
|
|
|
return lines(tick) - 1;
|
2015-09-01 06:19:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// bottomLine
|
|
|
|
// returns logical line number of bottom staff line
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
int Staff::bottomLine(int tick) const
|
2015-09-01 06:19:20 +02:00
|
|
|
{
|
2016-12-23 12:05:18 +01:00
|
|
|
return (lines(tick) - 1) * 2;
|
2015-09-01 06:19:20 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// slashStyle
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
bool Staff::slashStyle(int tick) const
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
return staffType(tick)->slashStyle();
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setSlashStyle
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
void Staff::setSlashStyle(int tick, bool val)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
staffType(tick)->setSlashStyle(val);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// linkTo
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::linkTo(Staff* staff)
|
|
|
|
{
|
|
|
|
if (!_linkedStaves) {
|
|
|
|
if (staff->linkedStaves()) {
|
|
|
|
_linkedStaves = staff->linkedStaves();
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
_linkedStaves = new LinkedStaves;
|
|
|
|
_linkedStaves->add(staff);
|
|
|
|
staff->setLinkedStaves(_linkedStaves);
|
|
|
|
}
|
|
|
|
_linkedStaves->add(this);
|
|
|
|
}
|
|
|
|
else {
|
2013-07-16 18:16:16 +02:00
|
|
|
_linkedStaves->add(staff);
|
2014-05-22 16:18:35 +02:00
|
|
|
if (!staff->linkedStaves())
|
|
|
|
staff->_linkedStaves = _linkedStaves;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-08-01 16:21:39 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// unlink
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::unlink(Staff* staff)
|
|
|
|
{
|
2014-08-11 15:25:55 +02:00
|
|
|
if (!_linkedStaves)
|
|
|
|
return;
|
2016-03-17 13:42:52 +01:00
|
|
|
if (!_linkedStaves->staves().contains(staff))
|
|
|
|
return;
|
2014-08-01 16:21:39 +02:00
|
|
|
_linkedStaves->remove(staff);
|
2014-08-07 19:39:18 +02:00
|
|
|
if (_linkedStaves->staves().size() <= 1) {
|
|
|
|
delete _linkedStaves;
|
|
|
|
_linkedStaves = 0;
|
|
|
|
}
|
|
|
|
staff->_linkedStaves = 0;
|
2014-08-01 16:21:39 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// add
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void LinkedStaves::add(Staff* staff)
|
|
|
|
{
|
2016-02-19 13:47:21 +01:00
|
|
|
if (!_staves.contains(staff))
|
|
|
|
_staves.append(staff);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// remove
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void LinkedStaves::remove(Staff* staff)
|
|
|
|
{
|
|
|
|
_staves.removeOne(staff);
|
|
|
|
}
|
|
|
|
|
2013-10-10 15:41:25 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// isLinked
|
|
|
|
/// return true if staff is different and
|
|
|
|
/// linked to this staff
|
|
|
|
//---------------------------------------------------------
|
2014-04-24 15:03:03 +02:00
|
|
|
|
2013-10-10 15:41:25 +02:00
|
|
|
bool Staff::isLinked(Staff* staff)
|
|
|
|
{
|
|
|
|
if (staff == this || !_linkedStaves)
|
|
|
|
return false;
|
|
|
|
|
|
|
|
for(Staff* s : _linkedStaves->staves()) {
|
|
|
|
if(s == staff)
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// primaryStaff
|
|
|
|
/// if there are linked staves, the primary staff is
|
2015-06-22 17:59:08 +02:00
|
|
|
/// the one who is played back and it's not a tab staff
|
|
|
|
/// because we don't have enough information to play
|
|
|
|
/// e.g ornaments. NOTE: it's not necessarily the top staff!
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::primaryStaff() const
|
|
|
|
{
|
|
|
|
if (!_linkedStaves)
|
|
|
|
return true;
|
2015-06-22 18:19:05 +02:00
|
|
|
QList<Staff*> s;
|
|
|
|
QList<Staff*> ss;
|
2012-05-26 14:26:10 +02:00
|
|
|
foreach(Staff* staff, _linkedStaves->staves()) {
|
2015-06-22 18:19:05 +02:00
|
|
|
if (staff->score() == score()) {
|
2012-05-26 14:26:10 +02:00
|
|
|
s.append(staff);
|
2016-12-13 13:16:17 +01:00
|
|
|
if (!staff->isTabStaff(0))
|
2015-06-22 18:19:05 +02:00
|
|
|
ss.append(staff);
|
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2015-06-22 18:19:05 +02:00
|
|
|
if (s.size() == 1) // the linked staves are in different scores
|
|
|
|
return s.front() == this;
|
|
|
|
else // return a non tab linked staff in this score
|
|
|
|
return ss.front() == this;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// staffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
const StaffType* Staff::staffType(int tick) const
|
|
|
|
{
|
|
|
|
return &_staffTypeList.staffType(tick);
|
|
|
|
}
|
|
|
|
|
|
|
|
StaffType* Staff::staffType(int tick)
|
|
|
|
{
|
|
|
|
return &_staffTypeList.staffType(tick);
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
2016-12-18 14:31:13 +01:00
|
|
|
// staffTypeListChanged
|
|
|
|
// Signal that the staffTypeList has changed at
|
|
|
|
// position tick. Update layout range.
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-18 14:31:13 +01:00
|
|
|
void Staff::staffTypeListChanged(int tick)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
2016-12-18 14:31:13 +01:00
|
|
|
score()->setLayout(tick);
|
|
|
|
auto i = _staffTypeList.find(tick);
|
|
|
|
++i;
|
|
|
|
if (i != _staffTypeList.end())
|
|
|
|
score()->setLayout(i->first);
|
2016-12-19 10:33:35 +01:00
|
|
|
else
|
|
|
|
score()->setLayout(score()->lastMeasure()->endTick());
|
2016-12-18 14:31:13 +01:00
|
|
|
}
|
2016-12-14 09:56:16 +01:00
|
|
|
|
2016-12-18 14:31:13 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// setStaffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
StaffType* Staff::setStaffType(int tick, const StaffType* nst)
|
|
|
|
{
|
|
|
|
auto i = _staffTypeList.find(tick);
|
|
|
|
if (i != _staffTypeList.end()) {
|
|
|
|
qDebug("there is alread a type at %d", tick);
|
2012-11-05 20:31:57 +01:00
|
|
|
}
|
2016-12-18 14:31:13 +01:00
|
|
|
return _staffTypeList.setStaffType(tick, nst);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// init
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-03-25 20:39:24 +01:00
|
|
|
void Staff::init(const InstrumentTemplate* t, const StaffType* staffType, int cidx)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
// set staff-type-independent parameters
|
|
|
|
if (cidx > MAX_STAVES) {
|
2016-12-23 12:05:18 +01:00
|
|
|
setSmall(0, false);
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
else {
|
2017-07-21 15:20:11 +02:00
|
|
|
setSmall(0, t->smallStaff[cidx]);
|
2017-03-31 13:03:15 +02:00
|
|
|
setBracketType(0, t->bracket[cidx]);
|
2012-05-26 14:26:10 +02:00
|
|
|
setBracketSpan(0, t->bracketSpan[cidx]);
|
|
|
|
setBarLineSpan(t->barlineSpan[cidx]);
|
|
|
|
}
|
2014-04-30 10:08:38 +02:00
|
|
|
const StaffType* pst = staffType ? staffType : t->staffTypePreset;
|
|
|
|
if (!pst)
|
|
|
|
pst = StaffType::getDefaultPreset(t->staffGroup);
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
setStaffType(0, pst);
|
2014-08-16 11:21:56 +02:00
|
|
|
setDefaultClefType(t->clefType(cidx));
|
2015-03-03 17:32:13 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// init
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::init(const Staff* s)
|
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
_staffTypeList = s->_staffTypeList;
|
2015-03-03 17:32:13 +01:00
|
|
|
setDefaultClefType(s->defaultClefType());
|
2017-07-21 15:20:11 +02:00
|
|
|
for (BracketItem* i : s->_brackets){
|
|
|
|
BracketItem* ni = new BracketItem(*i);
|
|
|
|
ni->setScore(score());
|
|
|
|
_brackets.push_back(ni);
|
|
|
|
}
|
2015-03-04 16:38:34 +01:00
|
|
|
_barLineSpan = s->_barLineSpan;
|
|
|
|
_barLineFrom = s->_barLineFrom;
|
|
|
|
_barLineTo = s->_barLineTo;
|
|
|
|
_invisible = s->_invisible;
|
2015-08-04 19:53:54 +02:00
|
|
|
_hideWhenEmpty = s->_hideWhenEmpty;
|
|
|
|
_cutaway = s->_cutaway;
|
2015-03-04 16:38:34 +01:00
|
|
|
_showIfEmpty = s->_showIfEmpty;
|
|
|
|
_hideSystemBarLine = s->_hideSystemBarLine;
|
|
|
|
_color = s->_color;
|
|
|
|
_userDist = s->_userDist;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
2013-04-05 15:52:35 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// initFromStaffType
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::initFromStaffType(const StaffType* staffType)
|
|
|
|
{
|
|
|
|
// get staff type if given (if none, get default preset for default staff group)
|
2014-04-30 10:08:38 +02:00
|
|
|
if (!staffType)
|
2014-05-27 13:30:23 +02:00
|
|
|
staffType = StaffType::getDefaultPreset(StaffGroup::STANDARD);
|
2013-04-05 15:52:35 +02:00
|
|
|
|
|
|
|
// use selected staff type
|
2016-12-13 13:16:17 +01:00
|
|
|
setStaffType(0, staffType);
|
2013-04-05 15:52:35 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// spatiumChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::spatiumChanged(qreal oldValue, qreal newValue)
|
|
|
|
{
|
|
|
|
_userDist = (_userDist / oldValue) * newValue;
|
|
|
|
}
|
|
|
|
|
2012-08-01 22:15:58 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// show
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::show() const
|
|
|
|
{
|
|
|
|
return _part->show();
|
|
|
|
}
|
|
|
|
|
2013-07-16 09:03:47 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// genKeySig
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-06-22 10:55:22 +02:00
|
|
|
bool Staff::genKeySig()
|
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
if (staffType(0)->group() == StaffGroup::TAB)
|
2014-04-28 18:38:50 +02:00
|
|
|
return false;
|
|
|
|
else
|
2016-12-13 13:16:17 +01:00
|
|
|
return staffType(0)->genKeysig();
|
2013-06-22 10:55:22 +02:00
|
|
|
}
|
|
|
|
|
2013-07-16 09:03:47 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// showLedgerLines
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2016-12-13 13:16:17 +01:00
|
|
|
bool Staff::showLedgerLines(int tick)
|
2013-06-22 10:55:22 +02:00
|
|
|
{
|
2016-12-13 13:16:17 +01:00
|
|
|
return staffType(tick)->showLedgerLines();
|
2013-06-22 10:55:22 +02:00
|
|
|
}
|
|
|
|
|
2013-07-16 09:03:47 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// updateOttava
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-07-15 12:49:51 +02:00
|
|
|
void Staff::updateOttava()
|
|
|
|
{
|
|
|
|
int staffIdx = idx();
|
|
|
|
_pitchOffsets.clear();
|
|
|
|
for (auto i : score()->spanner()) {
|
|
|
|
const Spanner* s = i.second;
|
2017-01-18 14:16:33 +01:00
|
|
|
if (s->type() == ElementType::OTTAVA && s->staffIdx() == staffIdx) {
|
2014-07-15 12:49:51 +02:00
|
|
|
const Ottava* o = static_cast<const Ottava*>(s);
|
|
|
|
_pitchOffsets.setPitchOffset(o->tick(), o->pitchShift());
|
|
|
|
_pitchOffsets.setPitchOffset(o->tick2(), 0);
|
|
|
|
}
|
|
|
|
}
|
2013-07-16 09:03:47 +02:00
|
|
|
}
|
2013-10-26 13:47:05 +02:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// undoSetColor
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-01-15 22:05:05 +01:00
|
|
|
void Staff::undoSetColor(const QColor& /*val*/)
|
2013-10-26 13:47:05 +02:00
|
|
|
{
|
2016-06-09 09:26:13 +02:00
|
|
|
// undoChangeProperty(P_ID::COLOR, val);
|
2013-10-26 13:47:05 +02:00
|
|
|
}
|
|
|
|
|
2014-05-08 17:59:24 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// insertTime
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::insertTime(int tick, int len)
|
|
|
|
{
|
2015-02-17 21:12:19 +01:00
|
|
|
if (len == 0)
|
|
|
|
return;
|
2015-02-14 16:24:29 +01:00
|
|
|
|
2015-03-09 18:31:28 +01:00
|
|
|
// move all keys and clefs >= tick
|
|
|
|
|
|
|
|
if (len < 0) {
|
|
|
|
// remove entries between tickpos >= tick and tickpos < (tick+len)
|
|
|
|
_keys.erase(_keys.lower_bound(tick), _keys.lower_bound(tick-len));
|
|
|
|
clefs.erase(clefs.lower_bound(tick), clefs.lower_bound(tick-len));
|
|
|
|
}
|
2014-12-08 18:02:17 +01:00
|
|
|
|
2014-05-08 17:59:24 +02:00
|
|
|
KeyList kl2;
|
2015-03-09 18:31:28 +01:00
|
|
|
for (auto i = _keys.lower_bound(tick); i != _keys.end();) {
|
2014-12-08 18:02:17 +01:00
|
|
|
KeySigEvent kse = i->second;
|
2015-03-09 18:31:28 +01:00
|
|
|
int tick = i->first;
|
2014-06-03 15:28:10 +02:00
|
|
|
_keys.erase(i++);
|
2015-03-09 18:31:28 +01:00
|
|
|
kl2[tick + len] = kse;
|
2014-05-08 17:59:24 +02:00
|
|
|
}
|
2014-06-03 15:28:10 +02:00
|
|
|
_keys.insert(kl2.begin(), kl2.end());
|
2014-05-08 17:59:24 +02:00
|
|
|
|
2015-06-26 11:55:44 +02:00
|
|
|
// check if there is a clef at the end of measure
|
|
|
|
// before tick
|
|
|
|
Clef* clef = 0;
|
2016-03-10 10:41:31 +01:00
|
|
|
Measure* m = score()->tick2measure(tick);
|
2015-06-26 11:55:44 +02:00
|
|
|
if (m && (m->tick() == tick) && (m->prevMeasure())) {
|
|
|
|
m = m->prevMeasure();
|
2017-03-08 13:12:26 +01:00
|
|
|
Segment* s = m->findSegment(SegmentType::Clef, tick);
|
2015-06-26 11:55:44 +02:00
|
|
|
if (s) {
|
|
|
|
int track = idx() * VOICES;
|
2017-12-20 16:49:30 +01:00
|
|
|
clef = toClef(s->element(track));
|
2015-06-26 11:55:44 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-08 17:59:24 +02:00
|
|
|
ClefList cl2;
|
2015-03-09 18:31:28 +01:00
|
|
|
for (auto i = clefs.lower_bound(tick); i != clefs.end();) {
|
2014-05-08 17:59:24 +02:00
|
|
|
ClefTypeList ctl = i->second;
|
2015-06-26 11:55:44 +02:00
|
|
|
int t = i->first;
|
|
|
|
if (clef && tick == t) {
|
|
|
|
++i;
|
|
|
|
continue;
|
|
|
|
}
|
2014-05-08 17:59:24 +02:00
|
|
|
clefs.erase(i++);
|
2015-06-26 11:55:44 +02:00
|
|
|
cl2.setClef(t + len, ctl);
|
2014-05-08 17:59:24 +02:00
|
|
|
}
|
|
|
|
clefs.insert(cl2.begin(), cl2.end());
|
2015-06-09 17:20:17 +02:00
|
|
|
|
|
|
|
// check if there is a clef at the end of measure
|
|
|
|
// before tick: do not remove from clefs list
|
|
|
|
|
2015-06-26 11:55:44 +02:00
|
|
|
if (clef)
|
|
|
|
setClef(clef);
|
2015-06-09 17:20:17 +02:00
|
|
|
|
2015-02-21 16:07:37 +01:00
|
|
|
updateOttava();
|
2015-06-26 11:55:44 +02:00
|
|
|
DUMP_CLEFS(" insertTime");
|
2014-05-08 17:59:24 +02:00
|
|
|
}
|
|
|
|
|
2014-05-21 20:08:37 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// staffList
|
|
|
|
// return list of linked staves
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QList<Staff*> Staff::staffList() const
|
|
|
|
{
|
|
|
|
QList<Staff*> staffList;
|
|
|
|
if (_linkedStaves)
|
|
|
|
staffList = _linkedStaves->staves();
|
|
|
|
else
|
|
|
|
staffList.append(const_cast<Staff*>(this));
|
|
|
|
return staffList;
|
|
|
|
}
|
|
|
|
|
2014-08-11 15:25:55 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// rstaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::rstaff() const
|
|
|
|
{
|
|
|
|
return _part->staves()->indexOf((Staff*)this, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// isTop
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::isTop() const
|
|
|
|
{
|
|
|
|
return _part->staves()->front() == this;
|
|
|
|
}
|
2014-12-22 13:28:09 +01:00
|
|
|
|
2015-02-04 22:12:13 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// getProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QVariant Staff::getProperty(P_ID id) const
|
|
|
|
{
|
|
|
|
switch (id) {
|
2017-02-13 18:21:12 +01:00
|
|
|
case P_ID::SMALL:
|
|
|
|
return small(0);
|
2017-02-08 15:34:53 +01:00
|
|
|
case P_ID::MAG:
|
|
|
|
return userMag(0);
|
2015-02-04 22:12:13 +01:00
|
|
|
case P_ID::COLOR:
|
|
|
|
return color();
|
2016-09-16 12:07:37 +02:00
|
|
|
case P_ID::PLAYBACK_VOICE1:
|
|
|
|
return playbackVoice(0);
|
|
|
|
case P_ID::PLAYBACK_VOICE2:
|
|
|
|
return playbackVoice(1);
|
|
|
|
case P_ID::PLAYBACK_VOICE3:
|
|
|
|
return playbackVoice(2);
|
|
|
|
case P_ID::PLAYBACK_VOICE4:
|
|
|
|
return playbackVoice(3);
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN:
|
2016-09-17 12:27:19 +02:00
|
|
|
return barLineSpan();
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN_FROM:
|
2016-09-17 12:27:19 +02:00
|
|
|
return barLineFrom();
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN_TO:
|
2016-09-17 12:27:19 +02:00
|
|
|
return barLineTo();
|
2016-12-23 12:05:18 +01:00
|
|
|
case P_ID::STAFF_USERDIST:
|
|
|
|
return userDist();
|
2015-02-04 22:12:13 +01:00
|
|
|
default:
|
2016-12-29 13:42:55 +01:00
|
|
|
qDebug("unhandled id %s", propertyName(id));
|
2015-02-04 22:12:13 +01:00
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setProperty
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::setProperty(P_ID id, const QVariant& v)
|
|
|
|
{
|
|
|
|
switch (id) {
|
2017-02-13 18:21:12 +01:00
|
|
|
case P_ID::SMALL:
|
|
|
|
setSmall(0, v.toBool());
|
|
|
|
break;
|
2017-02-08 15:34:53 +01:00
|
|
|
case P_ID::MAG: {
|
|
|
|
qreal _spatium = spatium(0);
|
|
|
|
setUserMag(0, v.toReal());
|
|
|
|
score()->spatiumChanged(_spatium, spatium(0));
|
|
|
|
}
|
|
|
|
break;
|
2015-02-04 22:12:13 +01:00
|
|
|
case P_ID::COLOR:
|
|
|
|
setColor(v.value<QColor>());
|
|
|
|
break;
|
2016-09-16 12:07:37 +02:00
|
|
|
case P_ID::PLAYBACK_VOICE1:
|
|
|
|
setPlaybackVoice(0, v.toBool());
|
|
|
|
break;
|
|
|
|
case P_ID::PLAYBACK_VOICE2:
|
|
|
|
setPlaybackVoice(1, v.toBool());
|
|
|
|
break;
|
|
|
|
case P_ID::PLAYBACK_VOICE3:
|
|
|
|
setPlaybackVoice(2, v.toBool());
|
|
|
|
break;
|
|
|
|
case P_ID::PLAYBACK_VOICE4:
|
|
|
|
setPlaybackVoice(3, v.toBool());
|
|
|
|
break;
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN:
|
2016-09-17 12:27:19 +02:00
|
|
|
setBarLineSpan(v.toInt());
|
|
|
|
break;
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN_FROM:
|
2016-09-17 12:27:19 +02:00
|
|
|
setBarLineFrom(v.toInt());
|
|
|
|
break;
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN_TO:
|
2016-09-17 12:27:19 +02:00
|
|
|
setBarLineTo(v.toInt());
|
|
|
|
break;
|
2016-12-23 12:05:18 +01:00
|
|
|
case P_ID::STAFF_USERDIST:
|
|
|
|
setUserDist(v.toReal());
|
|
|
|
break;
|
2015-02-04 22:12:13 +01:00
|
|
|
default:
|
2016-12-29 13:42:55 +01:00
|
|
|
qDebug("unhandled id %s", propertyName(id));
|
2015-02-04 22:12:13 +01:00
|
|
|
break;
|
|
|
|
}
|
2016-03-02 13:20:19 +01:00
|
|
|
score()->setLayoutAll();
|
2015-02-04 22:12:13 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// propertyDefault
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
QVariant Staff::propertyDefault(P_ID id) const
|
|
|
|
{
|
|
|
|
switch (id) {
|
2017-02-13 18:21:12 +01:00
|
|
|
case P_ID::SMALL:
|
|
|
|
return false;
|
2017-02-08 15:34:53 +01:00
|
|
|
case P_ID::MAG:
|
|
|
|
return 1.0;
|
2015-02-04 22:12:13 +01:00
|
|
|
case P_ID::COLOR:
|
|
|
|
return QColor(Qt::black);
|
2016-09-16 12:07:37 +02:00
|
|
|
case P_ID::PLAYBACK_VOICE1:
|
|
|
|
case P_ID::PLAYBACK_VOICE2:
|
|
|
|
case P_ID::PLAYBACK_VOICE3:
|
|
|
|
case P_ID::PLAYBACK_VOICE4:
|
|
|
|
return true;
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN:
|
2016-12-23 12:05:18 +01:00
|
|
|
return false;
|
2016-12-28 16:23:10 +01:00
|
|
|
case P_ID::STAFF_BARLINE_SPAN_FROM:
|
|
|
|
case P_ID::STAFF_BARLINE_SPAN_TO:
|
2016-12-23 12:05:18 +01:00
|
|
|
return 0;
|
|
|
|
case P_ID::STAFF_USERDIST:
|
|
|
|
return qreal(0.0);
|
2015-02-04 22:12:13 +01:00
|
|
|
default:
|
2016-12-29 13:42:55 +01:00
|
|
|
qDebug("unhandled id %s", propertyName(id));
|
2015-02-04 22:12:13 +01:00
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
}
|
2015-02-20 11:56:13 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// scaleChanged
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::scaleChanged(double oldVal, double newVal)
|
|
|
|
{
|
|
|
|
int staffIdx = idx();
|
|
|
|
int startTrack = staffIdx * VOICES;
|
|
|
|
int endTrack = startTrack + VOICES;
|
2017-03-08 13:12:26 +01:00
|
|
|
for (Segment* s = score()->firstSegment(SegmentType::All); s; s = s->next1()) {
|
2015-02-20 11:56:13 +01:00
|
|
|
for (Element* e : s->annotations())
|
|
|
|
e->localSpatiumChanged(oldVal, newVal);
|
|
|
|
for (int track = startTrack; track < endTrack; ++track) {
|
|
|
|
if (s->element(track))
|
|
|
|
s->element(track)->localSpatiumChanged(oldVal, newVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (auto i : score()->spanner()) {
|
|
|
|
Spanner* spanner = i.second;
|
|
|
|
if (spanner->staffIdx() == staffIdx) {
|
|
|
|
for (auto k : spanner->spannerSegments())
|
|
|
|
k->localSpatiumChanged(oldVal, newVal);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-13 13:16:17 +01:00
|
|
|
|
2016-12-23 12:05:18 +01:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// isPitchedStaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::isPitchedStaff(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->group() == StaffGroup::STANDARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// isTabStaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::isTabStaff(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->group() == StaffGroup::TAB;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// isDrumStaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
bool Staff::isDrumStaff(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->group() == StaffGroup::PERCUSSION;
|
|
|
|
}
|
2016-12-13 13:16:17 +01:00
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// lines
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
int Staff::lines(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->lines();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// setLines
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
void Staff::setLines(int tick, int val)
|
|
|
|
{
|
|
|
|
staffType(tick)->setLines(val); // TODO: make undoable
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// lineDistance
|
|
|
|
// distance between staff lines
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
qreal Staff::lineDistance(int tick) const
|
|
|
|
{
|
|
|
|
return staffType(tick)->lineDistance().val();
|
|
|
|
}
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
|
|
|
|