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 "navigate.h"
|
|
|
|
#include "element.h"
|
|
|
|
#include "clef.h"
|
|
|
|
#include "score.h"
|
|
|
|
#include "note.h"
|
|
|
|
#include "rest.h"
|
|
|
|
#include "chord.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "segment.h"
|
|
|
|
#include "lyrics.h"
|
|
|
|
#include "harmony.h"
|
|
|
|
#include "utils.h"
|
|
|
|
#include "input.h"
|
|
|
|
#include "measure.h"
|
|
|
|
#include "page.h"
|
2014-06-20 22:48:34 +02:00
|
|
|
#include "spanner.h"
|
|
|
|
#include "system.h"
|
|
|
|
#include "staff.h"
|
|
|
|
#include "barline.h"
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
namespace Ms {
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// nextChordRest
|
2012-11-23 15:22:16 +01:00
|
|
|
// return next Chord or Rest
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-06-12 14:23:57 +02:00
|
|
|
ChordRest* nextChordRest(ChordRest* cr)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
if (!cr)
|
|
|
|
return 0;
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2013-06-16 23:33:37 +02:00
|
|
|
if (cr->isGrace()) {
|
2014-08-17 20:11:39 +02:00
|
|
|
//
|
2013-06-16 23:33:37 +02:00
|
|
|
// cr is a grace note
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2013-06-16 23:33:37 +02:00
|
|
|
Chord* c = static_cast<Chord*>(cr);
|
|
|
|
Chord* pc = static_cast<Chord*>(cr->parent());
|
2014-04-23 18:07:38 +02:00
|
|
|
|
2014-08-17 20:11:39 +02:00
|
|
|
if (cr->isGraceBefore()) {
|
|
|
|
QList<Chord*> graceNotesBefore;
|
2014-04-23 18:07:38 +02:00
|
|
|
pc->getGraceNotesBefore(&graceNotesBefore);
|
|
|
|
auto i = std::find(graceNotesBefore.begin(), graceNotesBefore.end(), c);
|
|
|
|
if (i == graceNotesBefore.end())
|
2014-08-17 20:11:39 +02:00
|
|
|
return 0; // unable to find self?
|
2014-04-23 18:07:38 +02:00
|
|
|
++i;
|
|
|
|
if (i != graceNotesBefore.end())
|
|
|
|
return *i;
|
2014-08-17 20:11:39 +02:00
|
|
|
// if this was last grace note before, return parent
|
|
|
|
return pc;
|
2014-04-23 18:07:38 +02:00
|
|
|
}
|
|
|
|
else {
|
2014-08-17 20:11:39 +02:00
|
|
|
QList<Chord*> graceNotesAfter;
|
|
|
|
pc->getGraceNotesAfter(&graceNotesAfter);
|
|
|
|
auto i = std::find(graceNotesAfter.begin(), graceNotesAfter.end(), c);
|
|
|
|
if (i == graceNotesAfter.end())
|
|
|
|
return 0; // unable to find self?
|
|
|
|
++i;
|
|
|
|
if (i != graceNotesAfter.end())
|
|
|
|
return *i;
|
|
|
|
// if this was last grace note after, fall through to find next main note
|
|
|
|
cr = pc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
//
|
|
|
|
// cr is not a grace note
|
|
|
|
if (cr->type() == Element::Type::CHORD) {
|
|
|
|
Chord* c = static_cast<Chord*>(cr);
|
|
|
|
if (!c->graceNotes().empty()) {
|
|
|
|
QList<Chord*> graceNotesAfter;
|
|
|
|
c->getGraceNotesAfter(&graceNotesAfter);
|
|
|
|
if (!graceNotesAfter.isEmpty())
|
|
|
|
return graceNotesAfter.first();
|
2014-04-23 18:07:38 +02:00
|
|
|
}
|
|
|
|
}
|
2013-06-16 23:33:37 +02:00
|
|
|
}
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
int track = cr->track();
|
2014-06-25 11:46:10 +02:00
|
|
|
Segment::Type st = Segment::Type::ChordRest;
|
2012-11-23 15:22:16 +01:00
|
|
|
|
2014-11-22 11:46:47 +01:00
|
|
|
for (Segment* seg = cr->segment()->next1MM(st); seg; seg = seg->next1MM(st)) {
|
2012-11-23 15:22:16 +01:00
|
|
|
ChordRest* e = static_cast<ChordRest*>(seg->element(track));
|
2013-06-16 23:33:37 +02:00
|
|
|
if (e) {
|
2014-06-24 18:36:02 +02:00
|
|
|
if (e->type() == Element::Type::CHORD) {
|
2013-06-16 23:33:37 +02:00
|
|
|
Chord* c = static_cast<Chord*>(e);
|
2014-08-17 20:11:39 +02:00
|
|
|
if (!c->graceNotes().empty()) {
|
|
|
|
QList<Chord*> graceNotesBefore;
|
|
|
|
c->getGraceNotesBefore(&graceNotesBefore);
|
|
|
|
if (!graceNotesBefore.isEmpty())
|
|
|
|
return graceNotesBefore.first();
|
|
|
|
}
|
2013-06-16 23:33:37 +02:00
|
|
|
}
|
2012-11-23 15:22:16 +01:00
|
|
|
return e;
|
2013-06-16 23:33:37 +02:00
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// prevChordRest
|
|
|
|
// return previous Chord or Rest
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-06-12 14:23:57 +02:00
|
|
|
ChordRest* prevChordRest(ChordRest* cr)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
if (!cr)
|
|
|
|
return 0;
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2013-06-16 23:33:37 +02:00
|
|
|
if (cr->isGrace()) {
|
2014-08-17 20:11:39 +02:00
|
|
|
//
|
2013-06-16 23:33:37 +02:00
|
|
|
// cr is a grace note
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2013-06-16 23:33:37 +02:00
|
|
|
Chord* c = static_cast<Chord*>(cr);
|
|
|
|
Chord* pc = static_cast<Chord*>(cr->parent());
|
2014-04-23 18:07:38 +02:00
|
|
|
|
2014-08-17 20:11:39 +02:00
|
|
|
if (cr->isGraceBefore()) {
|
|
|
|
QList<Chord*> graceNotesBefore;
|
2014-04-23 18:07:38 +02:00
|
|
|
pc->getGraceNotesBefore(&graceNotesBefore);
|
2014-08-17 20:11:39 +02:00
|
|
|
auto i = std::find(graceNotesBefore.begin(), graceNotesBefore.end(), c);
|
2014-04-23 18:07:38 +02:00
|
|
|
if (i == graceNotesBefore.end())
|
2014-08-17 20:11:39 +02:00
|
|
|
return 0; // unable to find self?
|
|
|
|
if (i != graceNotesBefore.begin())
|
2014-04-23 18:07:38 +02:00
|
|
|
return *--i;
|
2014-08-17 20:11:39 +02:00
|
|
|
// if this was first grace note before, fall through to find previous main note
|
|
|
|
cr = pc;
|
2014-04-23 18:07:38 +02:00
|
|
|
}
|
|
|
|
else {
|
2014-08-17 20:11:39 +02:00
|
|
|
QList<Chord*> graceNotesAfter;
|
|
|
|
pc->getGraceNotesAfter(&graceNotesAfter);
|
|
|
|
auto i = std::find(graceNotesAfter.begin(), graceNotesAfter.end(), c);
|
|
|
|
if (i == graceNotesAfter.end())
|
|
|
|
return 0; // unable to find self?
|
|
|
|
if (i != graceNotesAfter.begin())
|
|
|
|
return *--i;
|
|
|
|
// if this was first grace note after, return parent
|
|
|
|
return pc;
|
2014-04-23 18:07:38 +02:00
|
|
|
}
|
2013-06-16 23:33:37 +02:00
|
|
|
}
|
|
|
|
else {
|
2014-08-17 20:11:39 +02:00
|
|
|
//
|
|
|
|
// cr is not a grace note
|
2014-06-24 18:36:02 +02:00
|
|
|
if (cr->type() == Element::Type::CHORD) {
|
2013-06-16 23:33:37 +02:00
|
|
|
Chord* c = static_cast<Chord*>(cr);
|
2014-08-17 20:11:39 +02:00
|
|
|
if (!c->graceNotes().empty()) {
|
|
|
|
QList<Chord*> graceNotesBefore;
|
|
|
|
c->getGraceNotesBefore(&graceNotesBefore);
|
|
|
|
if (!graceNotesBefore.isEmpty())
|
|
|
|
return graceNotesBefore.last();
|
|
|
|
}
|
2013-06-16 23:33:37 +02:00
|
|
|
}
|
|
|
|
}
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
int track = cr->track();
|
2014-06-25 11:46:10 +02:00
|
|
|
Segment::Type st = Segment::Type::ChordRest;
|
2014-11-25 16:53:43 +01:00
|
|
|
for (Segment* seg = cr->segment()->prev1MM(st); seg; seg = seg->prev1MM(st)) {
|
2012-11-23 15:22:16 +01:00
|
|
|
ChordRest* e = static_cast<ChordRest*>(seg->element(track));
|
2014-08-17 20:11:39 +02:00
|
|
|
if (e) {
|
|
|
|
if (e->type() == Element::Type::CHORD) {
|
|
|
|
Chord* c = static_cast<Chord*>(e);
|
|
|
|
if (!c->graceNotes().empty()) {
|
|
|
|
QList<Chord*> graceNotesAfter;
|
|
|
|
c->getGraceNotesAfter(&graceNotesAfter);
|
|
|
|
if (!graceNotesAfter.isEmpty())
|
|
|
|
return graceNotesAfter.last();
|
|
|
|
}
|
|
|
|
}
|
2012-11-23 15:22:16 +01:00
|
|
|
return e;
|
2014-08-17 20:11:39 +02:00
|
|
|
}
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
2014-08-17 20:11:39 +02:00
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// upAlt
|
2013-08-06 14:48:38 +02:00
|
|
|
// element: Note() or Rest()
|
|
|
|
// return: Note() or Rest()
|
|
|
|
//
|
2013-08-03 03:12:23 +02:00
|
|
|
// return next higher pitched note in chord
|
|
|
|
// move to previous track if at top of chord
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-08-06 14:48:38 +02:00
|
|
|
Element* Score::upAlt(Element* element)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
Element* re = 0;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (element->type() == Element::Type::REST)
|
2013-08-06 14:48:38 +02:00
|
|
|
re = prevTrack(static_cast<Rest*>(element));
|
2014-06-24 18:36:02 +02:00
|
|
|
else if (element->type() == Element::Type::NOTE) {
|
2013-08-03 03:12:23 +02:00
|
|
|
Chord* chord = static_cast<Note*>(element)->chord();
|
2013-08-06 14:48:38 +02:00
|
|
|
const QList<Note*>& notes = chord->notes();
|
2013-08-03 03:12:23 +02:00
|
|
|
int idx = notes.indexOf(static_cast<Note*>(element));
|
|
|
|
if (idx < notes.size()-1) {
|
|
|
|
++idx;
|
|
|
|
re = notes.value(idx);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
re = prevTrack(chord);
|
|
|
|
if (re->track() == chord->track())
|
|
|
|
re = element;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (re == 0)
|
|
|
|
return 0;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (re->type() == Element::Type::CHORD)
|
2013-08-06 14:48:38 +02:00
|
|
|
re = static_cast<Chord*>(re)->notes().front();
|
|
|
|
return re;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// upAltCtrl
|
|
|
|
// select top note in chord
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Note* Score::upAltCtrl(Note* note) const
|
|
|
|
{
|
|
|
|
return note->chord()->upNote();
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// downAlt
|
2013-08-03 03:12:23 +02:00
|
|
|
// return next lower pitched note in chord
|
|
|
|
// move to previous track if at bottom of chord
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2013-08-06 14:48:38 +02:00
|
|
|
Element* Score::downAlt(Element* element)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
Element* re = 0;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (element->type() == Element::Type::REST)
|
2013-08-06 14:48:38 +02:00
|
|
|
re = nextTrack(static_cast<Rest*>(element));
|
2014-06-24 18:36:02 +02:00
|
|
|
else if (element->type() == Element::Type::NOTE) {
|
2013-08-03 03:12:23 +02:00
|
|
|
Chord* chord = static_cast<Note*>(element)->chord();
|
2013-08-06 14:48:38 +02:00
|
|
|
const QList<Note*>& notes = chord->notes();
|
2013-08-03 03:12:23 +02:00
|
|
|
int idx = notes.indexOf(static_cast<Note*>(element));
|
|
|
|
if (idx > 0) {
|
|
|
|
--idx;
|
|
|
|
re = notes.value(idx);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
re = nextTrack(chord);
|
|
|
|
if (re->track() == chord->track())
|
|
|
|
re = element;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
if (re == 0)
|
|
|
|
return 0;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (re->type() == Element::Type::CHORD)
|
2013-08-06 14:48:38 +02:00
|
|
|
re = static_cast<Chord*>(re)->notes().back();
|
|
|
|
return re;
|
2012-05-26 14:26:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// downAltCtrl
|
|
|
|
// niedrigste Note in Chord selektieren
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Note* Score::downAltCtrl(Note* note) const
|
|
|
|
{
|
|
|
|
return note->chord()->downNote();
|
|
|
|
}
|
|
|
|
|
2014-06-20 22:48:34 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// firstElement
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Element* Score::firstElement()
|
|
|
|
{
|
|
|
|
return this->firstSegment()->element(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// lastElement
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
Element* Score::lastElement()
|
|
|
|
{
|
|
|
|
Element* re =0;
|
|
|
|
Segment* seg = this->lastSegment();
|
|
|
|
while (true) {
|
|
|
|
for(int i = (this->staves().size() -1) * VOICES; i < this->staves().size() * VOICES; i++){
|
|
|
|
if(seg->element(i) != 0){
|
|
|
|
re = seg->element(i);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(re){
|
|
|
|
if(re->type() == Element::Type::CHORD){
|
|
|
|
return static_cast<Chord*>(re)->notes().first();
|
|
|
|
}
|
|
|
|
return re;
|
|
|
|
}
|
|
|
|
seg = seg->prev1MM(Segment::Type::All);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// upStaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ChordRest* Score::upStaff(ChordRest* cr)
|
|
|
|
{
|
|
|
|
Segment* segment = cr->segment();
|
|
|
|
|
|
|
|
if (cr->staffIdx() == 0)
|
|
|
|
return cr;
|
|
|
|
|
|
|
|
for (int track = (cr->staffIdx() - 1) * VOICES; track >= 0; --track) {
|
|
|
|
Element* el = segment->element(track);
|
|
|
|
if (!el)
|
|
|
|
continue;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (el->type() == Element::Type::NOTE)
|
2012-05-26 14:26:10 +02:00
|
|
|
el = static_cast<Note*>(el)->chord();
|
|
|
|
if (el->isChordRest())
|
|
|
|
return static_cast<ChordRest*>(el);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// downStaff
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ChordRest* Score::downStaff(ChordRest* cr)
|
|
|
|
{
|
|
|
|
Segment* segment = cr->segment();
|
|
|
|
int tracks = nstaves() * VOICES;
|
|
|
|
|
|
|
|
if (cr->staffIdx() == nstaves() - 1)
|
|
|
|
return cr;
|
|
|
|
|
|
|
|
for (int track = (cr->staffIdx() + 1) * VOICES; track < tracks; --track) {
|
|
|
|
Element* el = segment->element(track);
|
|
|
|
if (!el)
|
|
|
|
continue;
|
2014-06-24 18:36:02 +02:00
|
|
|
if (el->type() == Element::Type::NOTE)
|
2012-05-26 14:26:10 +02:00
|
|
|
el = static_cast<Note*>(el)->chord();
|
|
|
|
if (el->isChordRest())
|
|
|
|
return static_cast<ChordRest*>(el);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-08-02 23:45:45 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// nextTrack
|
2013-08-03 03:12:23 +02:00
|
|
|
// returns note at or just before current (cr) position
|
|
|
|
// in next track for this measure
|
2013-08-02 23:45:45 +02:00
|
|
|
// that contains such an element
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ChordRest* Score::nextTrack(ChordRest* cr)
|
|
|
|
{
|
|
|
|
if (!cr)
|
|
|
|
return 0;
|
|
|
|
|
2013-08-06 14:48:38 +02:00
|
|
|
ChordRest* el = 0;
|
2013-08-02 23:45:45 +02:00
|
|
|
Measure* measure = cr->measure();
|
|
|
|
int track = cr->track();
|
|
|
|
int tracks = nstaves() * VOICES;
|
|
|
|
|
|
|
|
while (!el) {
|
|
|
|
// find next non-empty track
|
|
|
|
while (++track < tracks){
|
|
|
|
if (measure->hasVoice(track))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// no more tracks, return original element
|
|
|
|
if (track == tracks)
|
|
|
|
return cr;
|
|
|
|
// find element at same or previous segment within this track
|
2014-06-25 11:46:10 +02:00
|
|
|
for (Segment* segment = cr->segment(); segment; segment = segment->prev(Segment::Type::ChordRest)) {
|
2013-08-06 14:48:38 +02:00
|
|
|
el = static_cast<ChordRest*>(segment->element(track));
|
2013-08-02 23:45:45 +02:00
|
|
|
if (el)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-08-06 14:48:38 +02:00
|
|
|
return el;
|
2013-08-02 23:45:45 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// prevTrack
|
2013-08-03 03:12:23 +02:00
|
|
|
// returns ChordRest at or just before current (cr) position
|
|
|
|
// in previous track for this measure
|
2013-08-02 23:45:45 +02:00
|
|
|
// that contains such an element
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
|
|
|
ChordRest* Score::prevTrack(ChordRest* cr)
|
|
|
|
{
|
|
|
|
if (!cr)
|
|
|
|
return 0;
|
|
|
|
|
2013-08-06 14:48:38 +02:00
|
|
|
ChordRest* el = 0;
|
2013-08-02 23:45:45 +02:00
|
|
|
Measure* measure = cr->measure();
|
|
|
|
int track = cr->track();
|
|
|
|
|
|
|
|
while (!el) {
|
|
|
|
// find next non-empty track
|
|
|
|
while (--track >= 0){
|
|
|
|
if (measure->hasVoice(track))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
// no more tracks, return original element
|
|
|
|
if (track < 0)
|
|
|
|
return cr;
|
|
|
|
// find element at same or previous segment within this track
|
2014-06-25 11:46:10 +02:00
|
|
|
for (Segment* segment = cr->segment(); segment != 0; segment = segment->prev(Segment::Type::ChordRest)) {
|
2013-08-06 14:48:38 +02:00
|
|
|
el = static_cast<ChordRest*>(segment->element(track));
|
2013-08-02 23:45:45 +02:00
|
|
|
if (el)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2013-08-06 14:48:38 +02:00
|
|
|
return el;
|
2013-08-02 23:45:45 +02:00
|
|
|
}
|
|
|
|
|
2012-05-26 14:26:10 +02:00
|
|
|
//---------------------------------------------------------
|
|
|
|
// nextMeasure
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-11-25 16:53:43 +01:00
|
|
|
ChordRest* Score::nextMeasure(ChordRest* element, bool selectBehavior, bool mmRest)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
if (!element)
|
|
|
|
return 0;
|
|
|
|
|
2014-11-25 16:53:43 +01:00
|
|
|
Measure* measure = 0;
|
|
|
|
if (mmRest)
|
|
|
|
measure = element->measure()->nextMeasureMM();
|
|
|
|
else
|
|
|
|
measure = element->measure()->nextMeasure();
|
|
|
|
|
2013-08-06 14:48:38 +02:00
|
|
|
if (measure == 0)
|
|
|
|
return 0;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2013-09-06 11:57:02 +02:00
|
|
|
int endTick = element->measure()->last()->nextChordRest(element->track(), true)->tick();
|
2013-08-06 14:48:38 +02:00
|
|
|
bool last = false;
|
2012-05-26 14:26:10 +02:00
|
|
|
|
2014-05-24 12:53:50 +02:00
|
|
|
if (selection().isRange()) {
|
2012-05-26 14:26:10 +02:00
|
|
|
if (element->tick() != endTick && selection().tickEnd() <= endTick) {
|
|
|
|
measure = element->measure();
|
|
|
|
last = true;
|
|
|
|
}
|
|
|
|
else if (element->tick() == endTick && selection().isEndActive())
|
|
|
|
last = true;
|
|
|
|
}
|
|
|
|
else if (element->tick() != endTick && selectBehavior) {
|
|
|
|
measure = element->measure();
|
|
|
|
last = true;
|
|
|
|
}
|
|
|
|
if (!measure) {
|
|
|
|
measure = element->measure();
|
|
|
|
last = true;
|
|
|
|
}
|
|
|
|
int staff = element->staffIdx();
|
|
|
|
|
|
|
|
Segment* startSeg = last ? measure->last() : measure->first();
|
|
|
|
for (Segment* seg = startSeg; seg; seg = last ? seg->prev() : seg->next()) {
|
|
|
|
int etrack = (staff+1) * VOICES;
|
|
|
|
for (int track = staff * VOICES; track < etrack; ++track) {
|
|
|
|
Element* pel = seg->element(track);
|
|
|
|
|
|
|
|
if (pel && pel->isChordRest())
|
|
|
|
return static_cast<ChordRest*>(pel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//---------------------------------------------------------
|
|
|
|
// prevMeasure
|
|
|
|
//---------------------------------------------------------
|
|
|
|
|
2014-11-25 16:53:43 +01:00
|
|
|
ChordRest* Score::prevMeasure(ChordRest* element, bool mmRest)
|
2012-05-26 14:26:10 +02:00
|
|
|
{
|
|
|
|
if (!element)
|
|
|
|
return 0;
|
|
|
|
|
2014-11-25 16:53:43 +01:00
|
|
|
Measure* measure = 0;
|
|
|
|
if (mmRest)
|
|
|
|
measure = element->measure()->prevMeasureMM();
|
|
|
|
else
|
|
|
|
measure = element->measure()->prevMeasure();
|
2012-05-26 14:26:10 +02:00
|
|
|
|
|
|
|
int startTick = element->measure()->first()->nextChordRest(element->track())->tick();
|
|
|
|
bool last = false;
|
|
|
|
|
2014-05-24 12:53:50 +02:00
|
|
|
if ((selection().isRange())
|
2014-06-20 22:48:34 +02:00
|
|
|
&& selection().isEndActive() && selection().startSegment()->tick() <= startTick)
|
2012-05-26 14:26:10 +02:00
|
|
|
last = true;
|
|
|
|
else if (element->tick() != startTick) {
|
|
|
|
measure = element->measure();
|
|
|
|
}
|
|
|
|
if (!measure) {
|
|
|
|
measure = element->measure();
|
|
|
|
last = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int staff = element->staffIdx();
|
|
|
|
|
|
|
|
Segment* startSeg = last ? measure->last() : measure->first();
|
|
|
|
for (Segment* seg = startSeg; seg; seg = last ? seg->prev() : seg->next()) {
|
|
|
|
int etrack = (staff+1) * VOICES;
|
|
|
|
for (int track = staff * VOICES; track < etrack; ++track) {
|
|
|
|
Element* pel = seg->element(track);
|
|
|
|
|
|
|
|
if (pel && pel->isChordRest())
|
|
|
|
return static_cast<ChordRest*>(pel);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2013-05-13 18:49:17 +02:00
|
|
|
}
|
|
|
|
|