MuseScore/libmscore/barline.cpp

1662 lines
66 KiB
C++
Raw Normal View History

2012-05-26 14:26:10 +02:00
//=============================================================================
// MuseScore
// Music Composition & Notation
//
2016-12-29 15:11:28 +01:00
// Copyright (C) 2002-2016 Werner Schweer
2012-05-26 14:26:10 +02:00
//
// 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 "barline.h"
#include "score.h"
#include "sym.h"
#include "staff.h"
2016-12-23 12:05:18 +01:00
#include "part.h"
2012-05-26 14:26:10 +02:00
#include "system.h"
#include "measure.h"
#include "segment.h"
#include "articulation.h"
#include "stafftype.h"
2014-04-09 16:09:21 +02:00
#include "xml.h"
#include "marker.h"
2016-12-23 12:05:18 +01:00
#include "stafflines.h"
2017-03-08 14:18:34 +01:00
#include "spanner.h"
2018-01-04 14:31:13 +01:00
#include "undo.h"
#include "fermata.h"
#include "symbol.h"
#include "image.h"
2012-05-26 14:26:10 +02:00
2013-05-13 18:49:17 +02:00
namespace Ms {
2018-01-04 14:31:13 +01:00
//---------------------------------------------------------
// undoChangeBarLineType
//---------------------------------------------------------
static void undoChangeBarLineType(BarLine* bl, BarLineType barType, bool allStaves)
2018-01-04 14:31:13 +01:00
{
Measure* m = bl->measure();
if (!m)
return;
2018-01-04 14:31:13 +01:00
if (barType == BarLineType::START_REPEAT) {
m = m->nextMeasure();
if (!m)
return;
}
else if (bl->barLineType() == BarLineType::START_REPEAT) {
2019-04-06 07:54:38 +02:00
if (barType != BarLineType::END_REPEAT)
m->undoChangeProperty(Pid::REPEAT_START, false);
m = m->prevMeasure();
if (!m)
return;
}
2018-01-04 14:31:13 +01:00
switch (barType) {
case BarLineType::END:
case BarLineType::NORMAL:
case BarLineType::DOUBLE:
case BarLineType::BROKEN:
case BarLineType::DOTTED: {
Segment* segment = bl->segment();
2018-01-08 16:31:31 +01:00
SegmentType segmentType = segment->segmentType();
2018-01-04 14:31:13 +01:00
if (segmentType == SegmentType::EndBarLine) {
// when setting barline type on mmrest, set for underlying measure (and linked staves)
// createMMRest will then set for the mmrest directly
Measure* m2 = m->isMMRest() ? m->mmRestLast() : m;
bool generated;
if (bl->barLineType() == barType)
generated = bl->generated(); // no change: keep current status
else if (!bl->generated() && (barType == BarLineType::NORMAL))
generated = true; // currently non-generated, changing to normal: assume generated
else
generated = false; // otherwise assume non-generated
2019-04-13 19:37:21 +02:00
if (allStaves) {
// use all staves of master score; we will take care of parts in loop through linked staves below
m2 = bl->masterScore()->tick2measure(m2->tick());
if (!m2)
return; // should never happen
segment = m2->undoGetSegment(segment->segmentType(), segment->tick());
2019-04-13 19:37:21 +02:00
}
const std::vector<Element*>& elist = allStaves ? segment->elist() : std::vector<Element*> { bl };
for (Element* e : elist) {
if (!e || !e->staff() || !e->isBarLine())
continue;
// handle linked staves/parts:
// barlines themselves are not necessarily linked,
// so use staffList to find linked staves
BarLine* sbl = toBarLine(e);
for (Staff* lstaff : sbl->staff()->staffList()) {
Score* lscore = lstaff->score();
int ltrack = lstaff->idx() * VOICES;
// handle mmrests:
// set the barline on the underlying measure
// this will copied to the mmrest during layout, in createMMRest
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (!lmeasure)
continue;
lmeasure->undoChangeProperty(Pid::REPEAT_END, false);
Segment* lsegment = lmeasure->undoGetSegmentR(SegmentType::EndBarLine, lmeasure->ticks());
BarLine* lbl = toBarLine(lsegment->element(ltrack));
if (!lbl) {
lbl = new BarLine(lscore);
lbl->setParent(lsegment);
lbl->setTrack(ltrack);
lbl->setSpanStaff(lstaff->barLineSpan());
lbl->setSpanFrom(lstaff->barLineFrom());
lbl->setSpanTo(lstaff->barLineTo());
lbl->setBarLineType(barType);
lbl->setGenerated(generated);
lscore->addElement(lbl);
if (!generated)
lbl->linkTo(sbl);
}
else {
lscore->undo(new ChangeProperty(lbl, Pid::GENERATED, generated, PropertyFlags::NOSTYLE));
lscore->undo(new ChangeProperty(lbl, Pid::BARLINE_TYPE, QVariant::fromValue(barType), PropertyFlags::NOSTYLE));
// set generated flag before and after so it sticks on type change and also works on undo/redo
lscore->undo(new ChangeProperty(lbl, Pid::GENERATED, generated, PropertyFlags::NOSTYLE));
if (lbl != sbl && !generated && !lbl->links())
lscore->undo(new Link(lbl, sbl));
else if (lbl != sbl && generated && lbl->isLinked(sbl))
lscore->undo(new Unlink(lbl));
}
2018-01-04 14:31:13 +01:00
}
}
}
else if (segmentType == SegmentType::BeginBarLine) {
Segment* segment1 = m->undoGetSegmentR(SegmentType::BeginBarLine, Fraction(0, 1));
This commit contains changes required for MuseScore to compile under MSVC with no warnings. This commit contains changes required for MuseScore to compile under MSVC with no warnings. MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs. Most warnings are in the following categories: - Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes) - Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour. - Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out. - (Potentially) uninitialized local variable. Just initialized the vars. - foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"." Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types. - all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h) - awl/aslider.h: unreachable code. - awl/knob.cpp: name hiding - awl/mslider.cpp: name hiding - awl/slider.cpp: name hiding - bww2mxml/parser.cpp: name hiding - effects/compressor/compressor.cpp: narrowing conversion - effects/zita1/zitagui.cpp: name hiding - fluid/fluid.cpp: foreach replacement. Name hiding. - fluid/mod.cpp: name hiding. - fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars. - fluid/voice.cpp: Name hiding. - libmscore/accidental.cpp: Name hiding. - libmscore/ambitus.cpp: Initialize vars. - libmscore/barline.cpp: Name hiding. Unreachable code. - libmscore/beam.cpp: Name hiding. - libmscore/chordrest.cpp: Unreachable code. - libmscore/scorefile.cpp: Name hiding. - manual/genManual.cpp: Name hiding. foreach replacement. - midi/midifile.cpp: Name hiding. Unreachable code. - omr/importpdf.cpp: Name hiding. foreach replacement. - omr/omr.cpp: Name hiding. foreach replacement. - omr/omrpage.cpp: Name hiding. foreach replacement. - omr/omrview.cpp: Name hiding. foreach replacement. - synthesizer/event.cpp: Unreachable code. - zerberus\channel.cpp: Narrowing conversion. - zerberus\instrument.cpp: Name hiding. - zerberus\sfz.cpp: Name hiding. - zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union" - zerberus\zerberus.cpp: Name hiding. Unreferenced parameter. - zerberus\zerberusgui.cpp: Name hiding.
2018-05-03 03:04:08 +02:00
for (Element* e : segment1->elist()) {
2018-01-04 14:31:13 +01:00
if (e) {
e->score()->undo(new ChangeProperty(e, Pid::GENERATED, false, PropertyFlags::NOSTYLE));
2018-03-27 15:36:00 +02:00
e->score()->undo(new ChangeProperty(e, Pid::BARLINE_TYPE, QVariant::fromValue(barType), PropertyFlags::NOSTYLE));
// set generated flag before and after so it sticks on type change and also works on undo/redo
2018-03-27 15:36:00 +02:00
e->score()->undo(new ChangeProperty(e, Pid::GENERATED, false, PropertyFlags::NOSTYLE));
2018-01-04 14:31:13 +01:00
}
}
}
}
break;
case BarLineType::START_REPEAT: {
Measure* m2 = m->isMMRest() ? m->mmRestFirst() : m;
for (Score* lscore : m2->score()->scoreList()) {
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (lmeasure)
lmeasure->undoChangeProperty(Pid::REPEAT_START, true);
}
}
2018-01-04 14:31:13 +01:00
break;
case BarLineType::END_REPEAT: {
Measure* m2 = m->isMMRest() ? m->mmRestLast() : m;
for (Score* lscore : m2->score()->scoreList()) {
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (lmeasure)
lmeasure->undoChangeProperty(Pid::REPEAT_END, true);
}
}
2018-01-04 14:31:13 +01:00
break;
2019-04-06 07:54:38 +02:00
case BarLineType::END_START_REPEAT: {
Measure* m2 = m->isMMRest() ? m->mmRestLast() : m;
for (Score* lscore : m2->score()->scoreList()) {
Measure* lmeasure = lscore->tick2measure(m2->tick());
if (lmeasure) {
lmeasure->undoChangeProperty(Pid::REPEAT_END, true);
lmeasure = lmeasure->nextMeasure();
if (lmeasure)
lmeasure->undoChangeProperty(Pid::REPEAT_START, true);
}
2019-04-06 07:54:38 +02:00
}
}
break;
2018-01-04 14:31:13 +01:00
}
}
2012-10-14 00:35:11 +02:00
//---------------------------------------------------------
2017-06-02 10:27:32 +02:00
// BarLineEditData
2012-10-14 00:35:11 +02:00
//---------------------------------------------------------
2017-06-02 10:27:32 +02:00
class BarLineEditData : public ElementEditData {
public:
qreal yoff1;
qreal yoff2;
};
2012-10-14 00:35:11 +02:00
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
// BarLineTable
//---------------------------------------------------------
2012-05-26 14:26:10 +02:00
2016-06-13 17:39:10 +02:00
const std::vector<BarLineTableItem> BarLine::barLineTable {
2016-02-04 17:06:32 +01:00
{ BarLineType::NORMAL, QT_TRANSLATE_NOOP("Palette", "Normal barline"), "normal" },
{ BarLineType::DOUBLE, QT_TRANSLATE_NOOP("Palette", "Double barline"), "double" },
{ BarLineType::START_REPEAT, QT_TRANSLATE_NOOP("Palette", "Start repeat"), "start-repeat" },
{ BarLineType::END_REPEAT, QT_TRANSLATE_NOOP("Palette", "End repeat"), "end-repeat" },
{ BarLineType::BROKEN, QT_TRANSLATE_NOOP("Palette", "Dashed barline"), "dashed" },
{ BarLineType::END, QT_TRANSLATE_NOOP("Palette", "Final barline"), "end" },
2019-04-06 07:54:38 +02:00
{ BarLineType::END_START_REPEAT, QT_TRANSLATE_NOOP("Palette", "End-start repeat"), "end-start-repeat" },
2016-02-04 17:06:32 +01:00
{ BarLineType::DOTTED, QT_TRANSLATE_NOOP("Palette", "Dotted barline"), "dotted" },
2015-02-25 11:54:31 +01:00
};
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
// barLineTableItem
2015-02-25 11:54:31 +01:00
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
const BarLineTableItem* BarLine::barLineTableItem(unsigned i)
{
2016-06-13 17:39:10 +02:00
if (i >= barLineTable.size())
2016-02-04 17:06:32 +01:00
return 0;
return &barLineTable[i];
}
2014-03-24 11:50:26 +01:00
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
// userTypeName
2014-03-24 11:50:26 +01:00
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
QString BarLine::userTypeName(BarLineType t)
2014-03-24 11:50:26 +01:00
{
2016-02-04 17:06:32 +01:00
for (const auto& i : barLineTable) {
if (i.type == t)
return qApp->translate("Palette", i.userName);
}
return QString();
2014-03-24 11:50:26 +01:00
}
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
// barLineTypeName
//
// Instance form returning the name string of the bar line type and
// static form returning the name string for an arbitrary bar line type.
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
QString BarLine::barLineTypeName() const
{
return barLineTypeName(barLineType());
}
QString BarLine::barLineTypeName(BarLineType t)
{
for (const auto& i : barLineTable) {
if (i.type == t)
2016-02-04 17:06:32 +01:00
return i.name;
}
return QString("??");
}
//---------------------------------------------------------
// setBarLineType
//
// Set the bar line type from the type name string.
// Does not update _customSubtype or _generated flags: to be used when reading from a score file
//---------------------------------------------------------
void BarLine::setBarLineType(const QString& s)
{
_barLineType = barLineType(s);
}
//---------------------------------------------------------
// barLineType
//---------------------------------------------------------
BarLineType BarLine::barLineType(const QString& s)
{
for (const auto& i : barLineTable) {
if (i.name == s)
return i.type;
}
return BarLineType::NORMAL; // silent default
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// BarLine
//---------------------------------------------------------
BarLine::BarLine(Score* s)
: Element(s)
{
2016-12-18 14:31:13 +01:00
setHeight(4 * spatium()); // for use in palettes
2012-05-26 14:26:10 +02:00
}
2016-12-28 16:23:10 +01:00
BarLine::BarLine(const BarLine& bl)
: Element(bl)
{
_spanStaff = bl._spanStaff;
_spanFrom = bl._spanFrom;
_spanTo = bl._spanTo;
_barLineType = bl._barLineType;
y1 = bl.y1;
y2 = bl.y2;
for (Element* e : bl._el)
add(e->clone());
2016-12-28 16:23:10 +01:00
}
BarLine::~BarLine()
{
qDeleteAll(_el);
}
//---------------------------------------------------------
// canvasPos
//---------------------------------------------------------
QPointF BarLine::canvasPos() const
{
QPointF pos = Element::canvasPos();
if (parent()) {
System* system = measure()->system();
qreal yoff = system ? system->staff(staffIdx())->y() : 0.0;
pos.ry() += yoff;
}
return pos;
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// pagePos
//---------------------------------------------------------
QPointF BarLine::pagePos() const
{
2016-02-04 17:06:32 +01:00
if (segment() == 0)
2012-05-26 14:26:10 +02:00
return pos();
2016-02-04 17:06:32 +01:00
System* system = segment()->measure()->system();
2012-05-26 14:26:10 +02:00
qreal yp = y();
if (system) {
// get first not hidden staff
2016-12-23 12:05:18 +01:00
int startIdx = staffIdx();
2016-12-30 14:37:27 +01:00
int endIdx = startIdx + (spanStaff() ? 1 : 0);
2016-12-23 12:05:18 +01:00
int staffIdx1 = startIdx;
Staff* staff1 = score()->staff(staffIdx1);
SysStaff* sysStaff1 = system->staff(staffIdx1);
2016-12-23 12:05:18 +01:00
while (staff1 && sysStaff1 && !(sysStaff1->show() && staff1->show())) {
if (++staffIdx1 >= endIdx) {
// no visible staves spanned; just use first
staffIdx1 = startIdx;
break;
}
staff1 = score()->staff(staffIdx1);
sysStaff1 = system->staff(staffIdx1);
}
yp += system->staffYpage(staffIdx1);
}
2012-05-26 14:26:10 +02:00
return QPointF(pageX(), yp);
}
//---------------------------------------------------------
// prevVisiblespannedStaff
//---------------------------------------------------------
int prevVisibleSpannedStaff(const BarLine* bl)
{
Score* score = bl->score();
int staffIdx = bl->staffIdx();
Segment* segment = bl->segment();
for (int i = staffIdx - 1; i >= 0; --i) {
BarLine* nbl = toBarLine(segment->element(i * VOICES));
if (!nbl || !nbl->spanStaff())
break;
Staff* s = score->staff(i);
if (s->part()->show() && bl->measure()->visible(i)) {
return i;
}
}
return staffIdx;
}
//---------------------------------------------------------
// nextVisiblespannedStaff
//---------------------------------------------------------
int nextVisibleSpannedStaff(const BarLine* bl)
{
Score* score = bl->score();
int nstaves = score->nstaves();
int staffIdx = bl->staffIdx();
Segment* segment = bl->segment();
for (int i = staffIdx + 1; i < nstaves; ++i) {
Staff* s = score->staff(i);
if (s->part()->show() && bl->measure()->visible(i))
return i;
BarLine* nbl = toBarLine(segment->element(i * VOICES));
if (!nbl || !nbl->spanStaff())
break;
}
return staffIdx;
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// getY
//---------------------------------------------------------
2016-12-23 12:05:18 +01:00
void BarLine::getY() const
2012-05-26 14:26:10 +02:00
{
2012-10-14 00:35:11 +02:00
qreal _spatium = spatium();
2016-12-18 14:31:13 +01:00
if (!parent()) {
// for use in palette
2016-12-23 12:05:18 +01:00
y1 = _spanFrom * _spatium * .5;
y2 = (8-_spanTo) * _spatium * .5;
2016-12-18 14:31:13 +01:00
return;
}
int staffIdx1 = staffIdx();
const Staff* staff1 = score()->staff(staffIdx1);
int staffIdx2 = staffIdx1;
int nstaves = score()->nstaves();
2016-12-23 12:05:18 +01:00
2016-12-28 16:23:10 +01:00
Measure* measure = segment()->measure();
if (_spanStaff)
staffIdx2 = nextVisibleSpannedStaff(this);
2016-12-18 14:31:13 +01:00
System* system = measure->system();
2016-12-23 12:05:18 +01:00
if (!system)
2016-12-18 14:31:13 +01:00
return;
2016-12-23 12:05:18 +01:00
// test start and end staff visibility
2016-12-18 14:31:13 +01:00
// base y on top visible staff in barline span
// after skipping ones with hideSystemBarLine set
// and accounting for staves that are shown but have invisible measures
Fraction tick = segment()->measure()->tick();
const StaffType* st1 = staff1->staffType(tick);
2016-12-18 14:31:13 +01:00
2016-12-23 12:05:18 +01:00
int from = _spanFrom;
int to = _spanTo;
int oneLine = st1->lines() == 1;
if (oneLine && _spanFrom == 0) {
2016-12-18 14:31:13 +01:00
from = BARLINE_SPAN_1LINESTAFF_FROM;
if (!_spanStaff || (staffIdx1 == nstaves - 1))
to = BARLINE_SPAN_1LINESTAFF_TO;
}
2016-12-23 12:05:18 +01:00
SysStaff* sysStaff1 = system->staff(staffIdx1);
qreal yp = sysStaff1->y();
2017-03-20 18:24:16 +01:00
qreal spatium1 = st1->spatium(score());
qreal d = st1->lineDistance().val() * spatium1;
2016-12-23 12:05:18 +01:00
qreal yy = measure->staffLines(staffIdx1)->y1() - yp;
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleS(Sid::staffLineWidth).val() * spatium1 * .5;
2017-06-02 10:27:32 +02:00
y1 = yy + from * d * .5 - lw;
if (staffIdx2 != staffIdx1)
y2 = measure->staffLines(staffIdx2)->y1() - yp - to * d * .5;
2016-12-23 12:05:18 +01:00
else
y2 = yy + (st1->lines() * 2 - 2 + to) * d * .5 + lw;
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// drawDots
//---------------------------------------------------------
void BarLine::drawDots(QPainter* painter, qreal x) const
{
qreal _spatium = spatium();
This commit contains changes required for MuseScore to compile under MSVC with no warnings. This commit contains changes required for MuseScore to compile under MSVC with no warnings. MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs. Most warnings are in the following categories: - Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes) - Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour. - Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out. - (Potentially) uninitialized local variable. Just initialized the vars. - foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"." Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types. - all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h) - awl/aslider.h: unreachable code. - awl/knob.cpp: name hiding - awl/mslider.cpp: name hiding - awl/slider.cpp: name hiding - bww2mxml/parser.cpp: name hiding - effects/compressor/compressor.cpp: narrowing conversion - effects/zita1/zitagui.cpp: name hiding - fluid/fluid.cpp: foreach replacement. Name hiding. - fluid/mod.cpp: name hiding. - fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars. - fluid/voice.cpp: Name hiding. - libmscore/accidental.cpp: Name hiding. - libmscore/ambitus.cpp: Initialize vars. - libmscore/barline.cpp: Name hiding. Unreachable code. - libmscore/beam.cpp: Name hiding. - libmscore/chordrest.cpp: Unreachable code. - libmscore/scorefile.cpp: Name hiding. - manual/genManual.cpp: Name hiding. foreach replacement. - midi/midifile.cpp: Name hiding. Unreachable code. - omr/importpdf.cpp: Name hiding. foreach replacement. - omr/omr.cpp: Name hiding. foreach replacement. - omr/omrpage.cpp: Name hiding. foreach replacement. - omr/omrview.cpp: Name hiding. foreach replacement. - synthesizer/event.cpp: Unreachable code. - zerberus\channel.cpp: Narrowing conversion. - zerberus\instrument.cpp: Name hiding. - zerberus\sfz.cpp: Name hiding. - zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union" - zerberus\zerberus.cpp: Name hiding. Unreferenced parameter. - zerberus\zerberusgui.cpp: Name hiding.
2018-05-03 03:04:08 +02:00
qreal y1l;
qreal y2l;
if (parent() == 0) { // for use in palette (always Bravura)
//Bravura shifted repeatDot symbol 0.5sp upper in the font itself (1.272)
y1l = 1.5 * _spatium;
y2l = 2.5 * _spatium;
2012-05-26 14:26:10 +02:00
}
2016-02-04 17:06:32 +01:00
else {
const StaffType* st = staffType();
//workaround to make new Bravura font work correctly with repeatDots
qreal offset = score()->scoreFont()->name() == "Bravura" ? 0 : 0.5 * score()->spatium() * mag();
y1l = st->doty1() * _spatium + offset;
y2l = st->doty2() * _spatium + offset;
2016-12-23 12:05:18 +01:00
}
This commit contains changes required for MuseScore to compile under MSVC with no warnings. This commit contains changes required for MuseScore to compile under MSVC with no warnings. MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs. Most warnings are in the following categories: - Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes) - Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour. - Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out. - (Potentially) uninitialized local variable. Just initialized the vars. - foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"." Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types. - all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h) - awl/aslider.h: unreachable code. - awl/knob.cpp: name hiding - awl/mslider.cpp: name hiding - awl/slider.cpp: name hiding - bww2mxml/parser.cpp: name hiding - effects/compressor/compressor.cpp: narrowing conversion - effects/zita1/zitagui.cpp: name hiding - fluid/fluid.cpp: foreach replacement. Name hiding. - fluid/mod.cpp: name hiding. - fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars. - fluid/voice.cpp: Name hiding. - libmscore/accidental.cpp: Name hiding. - libmscore/ambitus.cpp: Initialize vars. - libmscore/barline.cpp: Name hiding. Unreachable code. - libmscore/beam.cpp: Name hiding. - libmscore/chordrest.cpp: Unreachable code. - libmscore/scorefile.cpp: Name hiding. - manual/genManual.cpp: Name hiding. foreach replacement. - midi/midifile.cpp: Name hiding. Unreachable code. - omr/importpdf.cpp: Name hiding. foreach replacement. - omr/omr.cpp: Name hiding. foreach replacement. - omr/omrpage.cpp: Name hiding. foreach replacement. - omr/omrview.cpp: Name hiding. foreach replacement. - synthesizer/event.cpp: Unreachable code. - zerberus\channel.cpp: Narrowing conversion. - zerberus\instrument.cpp: Name hiding. - zerberus\sfz.cpp: Name hiding. - zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union" - zerberus\zerberus.cpp: Name hiding. Unreferenced parameter. - zerberus\zerberusgui.cpp: Name hiding.
2018-05-03 03:04:08 +02:00
drawSymbol(SymId::repeatDot, painter, QPointF(x, y1l));
drawSymbol(SymId::repeatDot, painter, QPointF(x, y2l));
2016-12-23 12:05:18 +01:00
}
//---------------------------------------------------------
// drawTips
//---------------------------------------------------------
void BarLine::drawTips(QPainter* painter, bool reversed, qreal x) const
{
if (reversed) {
2017-08-06 17:07:16 +02:00
if (isTop())
drawSymbol(SymId::reversedBracketTop, painter, QPointF(x - symWidth(SymId::reversedBracketTop), y1));
if (isBottom())
drawSymbol(SymId::reversedBracketBottom, painter, QPointF(x - symWidth(SymId::reversedBracketBottom), y2));
2016-12-23 12:05:18 +01:00
}
else {
2017-08-06 17:07:16 +02:00
if (isTop())
drawSymbol(SymId::bracketTop, painter, QPointF(x, y1));
if (isBottom())
drawSymbol(SymId::bracketBottom, painter, QPointF(x, y2));
2016-12-23 12:05:18 +01:00
}
}
//---------------------------------------------------------
// isTop
//---------------------------------------------------------
bool BarLine::isTop() const
{
int idx = staffIdx();
if (idx == 0)
return true;
else
return (prevVisibleSpannedStaff(this) == idx);
2016-12-23 12:05:18 +01:00
}
//---------------------------------------------------------
// isBottom
//---------------------------------------------------------
bool BarLine::isBottom() const
{
if (!_spanStaff)
return true;
int idx = staffIdx();
if (idx == score()->nstaves() - 1)
return true;
else
return (nextVisibleSpannedStaff(this) == idx);
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// draw
//---------------------------------------------------------
void BarLine::draw(QPainter* painter) const
{
2016-08-06 11:36:51 +02:00
switch (barLineType()) {
2017-03-20 18:24:16 +01:00
case BarLineType::NORMAL: {
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
2017-03-20 18:24:16 +01:00
}
2016-12-28 17:20:02 +01:00
break;
2017-03-20 18:24:16 +01:00
case BarLineType::BROKEN: {
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw, Qt::DashLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
2017-03-20 18:24:16 +01:00
}
break;
2017-03-20 18:24:16 +01:00
case BarLineType::DOTTED: {
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw, Qt::DotLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
painter->drawLine(QLineF(lw * .5, y1, lw * .5, y2));
2017-03-20 18:24:16 +01:00
}
2016-12-29 15:11:28 +01:00
break;
2012-05-26 14:26:10 +02:00
2017-03-20 18:24:16 +01:00
case BarLineType::END: {
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
qreal x = lw * .5;
painter->drawLine(QLineF(x, y1, x, y2));
2018-03-27 15:36:00 +02:00
qreal lw2 = score()->styleP(Sid::endBarWidth) * mag();
2017-08-04 12:05:30 +02:00
painter->setPen(QPen(curColor(), lw2, Qt::SolidLine, Qt::FlatCap));
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::endBarDistance) * mag();
2017-08-04 12:05:30 +02:00
painter->drawLine(QLineF(x, y1, x, y2));
2012-05-26 14:26:10 +02:00
}
break;
2017-03-20 18:24:16 +01:00
case BarLineType::DOUBLE: {
2018-03-27 15:36:00 +02:00
qreal lw2 = score()->styleP(Sid::doubleBarWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw2, Qt::SolidLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
qreal x = lw2 * .5;
painter->drawLine(QLineF(x, y1, x, y2));
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::doubleBarDistance) * mag();
2012-05-26 14:26:10 +02:00
painter->drawLine(QLineF(x, y1, x, y2));
}
break;
2017-03-20 18:24:16 +01:00
case BarLineType::START_REPEAT: {
2018-03-27 15:36:00 +02:00
qreal lw2 = score()->styleP(Sid::endBarWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw2, Qt::SolidLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
qreal x = lw2 * .5;
painter->drawLine(QLineF(x, y1, x, y2));
2012-05-26 14:26:10 +02:00
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
2017-03-20 18:24:16 +01:00
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::endBarDistance) * mag();
2017-03-20 18:24:16 +01:00
painter->drawLine(QLineF(x, y1, x, y2));
2012-05-26 14:26:10 +02:00
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::repeatBarlineDotSeparation) * mag();
2017-08-04 12:05:30 +02:00
x -= symBbox(SymId::repeatDot).width() * .5;
2017-03-20 18:24:16 +01:00
drawDots(painter, x);
2018-03-27 15:36:00 +02:00
if (score()->styleB(Sid::repeatBarTips))
2017-08-06 17:07:16 +02:00
drawTips(painter, false, 0.0);
2012-05-26 14:26:10 +02:00
}
break;
2017-03-20 18:24:16 +01:00
case BarLineType::END_REPEAT: {
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * mag();
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
2017-08-04 12:05:30 +02:00
qreal x = 0.0; // symBbox(SymId::repeatDot).width() * .5;
drawDots(painter, x);
2016-12-23 12:05:18 +01:00
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::repeatBarlineDotSeparation) * mag();
2017-08-04 12:05:30 +02:00
x += symBbox(SymId::repeatDot).width() * .5;
painter->drawLine(QLineF(x, y1, x, y2));
2018-03-27 15:36:00 +02:00
x += score()->styleP(Sid::endBarDistance) * mag();
2017-08-04 12:05:30 +02:00
2018-03-27 15:36:00 +02:00
qreal lw2 = score()->styleP(Sid::endBarWidth) * mag();
2017-08-04 12:05:30 +02:00
painter->setPen(QPen(curColor(), lw2, Qt::SolidLine, Qt::FlatCap));
painter->drawLine(QLineF(x, y1, x, y2));
2016-12-23 12:05:18 +01:00
2018-03-27 15:36:00 +02:00
if (score()->styleB(Sid::repeatBarTips))
2017-08-06 17:07:16 +02:00
drawTips(painter, true, x + lw2 * .5);
2012-05-26 14:26:10 +02:00
}
break;
2019-04-06 07:54:38 +02:00
case BarLineType::END_START_REPEAT: {
qreal lw = score()->styleP(Sid::barWidth) * mag();
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
qreal x = 0.0; // symBbox(SymId::repeatDot).width() * .5;
drawDots(painter, x);
x += score()->styleP(Sid::repeatBarlineDotSeparation) * mag();
x += symBbox(SymId::repeatDot).width() * .5;
painter->drawLine(QLineF(x, y1, x, y2));
x += score()->styleP(Sid::endBarDistance) * mag();
qreal lw2 = score()->styleP(Sid::endBarWidth) * mag();
painter->setPen(QPen(curColor(), lw2, Qt::SolidLine, Qt::FlatCap));
painter->drawLine(QLineF(x, y1, x, y2));
if (score()->styleB(Sid::repeatBarTips))
drawTips(painter, true, x + lw2 * .5);
painter->setPen(QPen(curColor(), lw, Qt::SolidLine, Qt::FlatCap));
x += score()->styleP(Sid::endBarDistance) * mag();
painter->drawLine(QLineF(x, y1, x, y2));
x += score()->styleP(Sid::repeatBarlineDotSeparation) * mag();
x -= symBbox(SymId::repeatDot).width() * .5;
drawDots(painter, x);
if (score()->styleB(Sid::repeatBarTips))
drawTips(painter, false, 0.0);
}
break;
2012-05-26 14:26:10 +02:00
}
2016-08-06 11:36:51 +02:00
Segment* s = segment();
if (s && s->isEndBarLineType() && !score()->printing() && score()->showUnprintable()) {
2016-08-06 11:36:51 +02:00
Measure* m = s->measure();
2018-11-27 10:32:41 +01:00
if (m->isIrregular() && score()->markIrregularMeasures() && !m->isMMRest()) {
2016-08-06 11:36:51 +02:00
painter->setPen(MScore::layoutBreakColor);
QFont f("FreeSerif");
f.setPointSizeF(12 * spatium() * MScore::pixelRatio / SPATIUM20);
2016-08-06 11:36:51 +02:00
f.setBold(true);
QString str = m->ticks() > m->timesig() ? "+" : "-";
QRectF r = QFontMetricsF(f, MScore::paintDevice()).boundingRect(str);
2016-08-06 11:36:51 +02:00
painter->setFont(f);
painter->drawText(-r.width(), 0.0, str);
}
}
2012-05-26 14:26:10 +02:00
}
2017-06-02 10:27:32 +02:00
//---------------------------------------------------------
// drawEditMode
//---------------------------------------------------------
void BarLine::drawEditMode(QPainter* p, EditData& ed)
{
Element::drawEditMode(p, ed);
BarLineEditData* bed = static_cast<BarLineEditData*>(ed.getData(this));
y1 += bed->yoff1;
y2 += bed->yoff2;
QPointF pos(canvasPos());
2017-06-02 10:27:32 +02:00
p->translate(pos);
BarLine::draw(p);
p->translate(-pos);
y1 -= bed->yoff1;
y2 -= bed->yoff2;
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// write
//---------------------------------------------------------
2016-11-19 11:51:21 +01:00
void BarLine::write(XmlWriter& xml) const
2012-05-26 14:26:10 +02:00
{
xml.stag(this);
2018-07-23 12:14:52 +02:00
2018-03-27 15:36:00 +02:00
writeProperty(xml, Pid::BARLINE_TYPE);
writeProperty(xml, Pid::BARLINE_SPAN);
writeProperty(xml, Pid::BARLINE_SPAN_FROM);
writeProperty(xml, Pid::BARLINE_SPAN_TO);
2016-02-09 13:51:19 +01:00
for (const Element* e : _el)
2012-05-26 14:26:10 +02:00
e->write(xml);
Element::writeProperties(xml);
xml.etag();
}
//---------------------------------------------------------
// read
//---------------------------------------------------------
2013-01-11 18:10:18 +01:00
void BarLine::read(XmlReader& e)
2012-05-26 14:26:10 +02:00
{
2018-03-27 15:36:00 +02:00
resetProperty(Pid::BARLINE_SPAN);
resetProperty(Pid::BARLINE_SPAN_FROM);
resetProperty(Pid::BARLINE_SPAN_TO);
2016-02-09 13:51:19 +01:00
2013-01-11 18:10:18 +01:00
while (e.readNextStartElement()) {
const QStringRef& tag(e.name());
2016-02-09 13:51:19 +01:00
if (tag == "subtype")
setBarLineType(e.readElementText());
2017-03-04 15:01:42 +01:00
else if (tag == "span")
2016-12-23 12:05:18 +01:00
_spanStaff = e.readBool();
else if (tag == "spanFromOffset")
_spanFrom = e.readInt();
else if (tag == "spanToOffset")
_spanTo = e.readInt();
2012-05-26 14:26:10 +02:00
else if (tag == "Articulation") {
Articulation* a = new Articulation(score());
a->read(e);
add(a);
}
else if (tag == "Symbol") {
Symbol* s = new Symbol(score());
s->setTrack(track());
s->read(e);
add(s);
}
else if (tag == "Image") {
if (MScore::noImages)
e.skipCurrentElement();
else {
Image* image = new Image(score());
image->setTrack(track());
image->read(e);
add(image);
}
}
2012-05-26 14:26:10 +02:00
else if (!Element::readProperties(e))
2013-01-11 18:10:18 +01:00
e.unknown();
2012-05-26 14:26:10 +02:00
}
}
//---------------------------------------------------------
// acceptDrop
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
bool BarLine::acceptDrop(EditData& data) const
2012-05-26 14:26:10 +02:00
{
ElementType type = data.dropElement->type();
2018-01-04 12:41:42 +01:00
if (type == ElementType::BAR_LINE) {
2016-02-04 17:06:32 +01:00
return true;
2018-01-04 12:41:42 +01:00
}
else {
return ((type == ElementType::ARTICULATION || type == ElementType::FERMATA || type == ElementType::SYMBOL || type == ElementType::IMAGE)
2016-02-04 17:06:32 +01:00
&& segment()
2016-03-02 13:20:19 +01:00
&& segment()->isEndBarLineType());
}
// Prevent unreachable code warning
This commit contains changes required for MuseScore to compile under MSVC with no warnings. This commit contains changes required for MuseScore to compile under MSVC with no warnings. MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs. Most warnings are in the following categories: - Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes) - Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour. - Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out. - (Potentially) uninitialized local variable. Just initialized the vars. - foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"." Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types. - all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h) - awl/aslider.h: unreachable code. - awl/knob.cpp: name hiding - awl/mslider.cpp: name hiding - awl/slider.cpp: name hiding - bww2mxml/parser.cpp: name hiding - effects/compressor/compressor.cpp: narrowing conversion - effects/zita1/zitagui.cpp: name hiding - fluid/fluid.cpp: foreach replacement. Name hiding. - fluid/mod.cpp: name hiding. - fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars. - fluid/voice.cpp: Name hiding. - libmscore/accidental.cpp: Name hiding. - libmscore/ambitus.cpp: Initialize vars. - libmscore/barline.cpp: Name hiding. Unreachable code. - libmscore/beam.cpp: Name hiding. - libmscore/chordrest.cpp: Unreachable code. - libmscore/scorefile.cpp: Name hiding. - manual/genManual.cpp: Name hiding. foreach replacement. - midi/midifile.cpp: Name hiding. Unreachable code. - omr/importpdf.cpp: Name hiding. foreach replacement. - omr/omr.cpp: Name hiding. foreach replacement. - omr/omrpage.cpp: Name hiding. foreach replacement. - omr/omrview.cpp: Name hiding. foreach replacement. - synthesizer/event.cpp: Unreachable code. - zerberus\channel.cpp: Narrowing conversion. - zerberus\instrument.cpp: Name hiding. - zerberus\sfz.cpp: Name hiding. - zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union" - zerberus\zerberus.cpp: Name hiding. Unreferenced parameter. - zerberus\zerberusgui.cpp: Name hiding.
2018-05-03 03:04:08 +02:00
// return false;
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// drop
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
Element* BarLine::drop(EditData& data)
2012-05-26 14:26:10 +02:00
{
Element* e = data.dropElement;
2016-02-04 11:27:47 +01:00
2017-03-07 18:01:56 +01:00
if (e->isBarLine()) {
2016-02-17 14:54:23 +01:00
BarLine* bl = toBarLine(e);
BarLineType st = bl->barLineType();
2016-02-04 11:27:47 +01:00
// if no change in subtype or no change in span, do nothing
2016-12-18 14:31:13 +01:00
if (st == barLineType() && !bl->spanFrom() && !bl->spanTo()) {
2012-05-26 14:26:10 +02:00
delete e;
return 0;
}
// check if the new property can apply to this single bar line
2019-04-06 07:54:38 +02:00
BarLineType bt = BarLineType::START_REPEAT | BarLineType::END_REPEAT | BarLineType::END_START_REPEAT;
2017-03-07 18:01:56 +01:00
bool oldRepeat = barLineType() & bt;
2016-02-04 17:06:32 +01:00
bool newRepeat = bl->barLineType() & bt;
2016-02-04 11:27:47 +01:00
// if ctrl was used and repeats are not involved,
// or if drop refers to span rather than subtype =>
// single bar line drop
2016-02-04 11:27:47 +01:00
2016-12-18 14:31:13 +01:00
if ((data.control() && !oldRepeat && !newRepeat) || (bl->spanFrom() || bl->spanTo()) ) {
// if drop refers to span, update this bar line span
2016-12-18 14:31:13 +01:00
if (bl->spanFrom() || bl->spanTo()) {
// if dropped spanFrom or spanTo are below the middle of standard staff (5 lines)
2016-12-23 12:05:18 +01:00
// adjust to the number of staff lines
2016-12-18 14:31:13 +01:00
// TODO:barlines
2016-12-23 12:05:18 +01:00
int spanFrom = bl->spanFrom();
int spanTo = bl->spanTo();
2018-03-27 15:36:00 +02:00
undoChangeProperty(Pid::BARLINE_SPAN, false);
undoChangeProperty(Pid::BARLINE_SPAN_FROM, spanFrom);
undoChangeProperty(Pid::BARLINE_SPAN_TO, spanTo);
}
// if drop refers to subtype, update this bar line subtype
2019-04-06 07:54:38 +02:00
else {
undoChangeBarLineType(this, st, false);
2019-04-06 07:54:38 +02:00
}
}
2019-04-06 07:54:38 +02:00
else {
undoChangeBarLineType(this, st, true);
2019-04-06 07:54:38 +02:00
}
delete e;
2012-05-26 14:26:10 +02:00
}
2017-03-07 18:01:56 +01:00
else if (e->isArticulation()) {
2016-02-17 14:54:23 +01:00
Articulation* atr = toArticulation(e);
2012-05-26 14:26:10 +02:00
atr->setParent(this);
atr->setTrack(track());
score()->undoAddElement(atr);
return atr;
}
else if (e->isSymbol() || e->isImage()) {
e->setParent(this);
e->setTrack(track());
score()->undoAddElement(e);
return e;
}
else if (e->isFermata()) {
e->setPlacement(track() & 1 ? Placement::BELOW : Placement::ABOVE);
for (Element* el: segment()->annotations())
if (el->isFermata() && (el->track() == track())) {
if (el->subtype() == e->subtype()) {
delete e;
return el;
}
else {
e->setPlacement(el->placement());
e->setTrack(track());
e->setParent(segment());
score()->undoChangeElement(el, e);
return e;
}
}
e->setTrack(track());
e->setParent(segment());
score()->undoAddElement(e);
return e;
}
2012-05-26 14:26:10 +02:00
return 0;
}
//---------------------------------------------------------
// updateGrips
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
void BarLine::updateGrips(EditData& ed) const
2012-05-26 14:26:10 +02:00
{
2017-06-02 10:27:32 +02:00
const BarLineEditData* bed = static_cast<const BarLineEditData*>(ed.getData(this));
2018-03-27 15:36:00 +02:00
qreal lw = score()->styleP(Sid::barWidth) * staff()->mag(tick());
2016-12-23 12:05:18 +01:00
getY();
2017-06-02 10:27:32 +02:00
ed.grip[0].translate(QPointF(lw * .5, y1 + bed->yoff1) + pagePos());
ed.grip[1].translate(QPointF(lw * .5, y2 + bed->yoff2) + pagePos());
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// startEdit
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
void BarLine::startEdit(EditData& ed)
{
2017-03-31 13:03:15 +02:00
ed.grips = 2;
ed.curGrip = Grip::END;
2017-06-02 10:27:32 +02:00
BarLineEditData* bed = new BarLineEditData();
bed->e = this;
bed->yoff1 = 0;
bed->yoff2 = 0;
ed.addData(bed);
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// endEdit
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
void BarLine::endEdit(EditData&)
2012-05-26 14:26:10 +02:00
{
2016-12-23 12:05:18 +01:00
#if 0 // TODO
2016-03-08 09:46:33 +01:00
if (ctrlDrag) { // if single bar line edit
2016-12-23 12:05:18 +01:00
char newSpanStaff = _spanStaff; // copy edited span values
char newSpanFrom = _spanFrom;
char newSpanTo = _spanTo;
_spanStaff = _origSpanStaff; // restore original span values
_spanFrom = _origSpanFrom;
_spanTo = _origSpanTo;
// for mid-measure barline in root score, update parts
2016-03-10 10:41:31 +01:00
if (midMeasure && score()->isMaster() && score()->excerpts().size() > 0) {
int currIdx = staffIdx();
2016-02-04 17:06:32 +01:00
Measure* m = segment()->measure();
// change linked barlines as necessary
2016-12-23 12:05:18 +01:00
int lastIdx = currIdx + qMax(_span, newSpanStaff);
for (int idx = currIdx; idx < lastIdx; ++idx) {
Staff* staff = score()->staff(idx);
LinkedStaves* ls = staff->linkedStaves();
if (ls) {
for (Staff* lstaff : ls->staves()) {
Score* lscore = lstaff->score();
// don't change barlines in root score
if (lscore == staff->score())
continue;
// change barline only in top staff of part
if (lstaff != lscore->staff(0))
continue;
2016-12-23 12:05:18 +01:00
int spannedStaves = qMax(currIdx + newSpanStaff - idx, 0);
int lNewSpan = qMin(spannedStaves, lscore->nstaves());
Measure* lm = lscore->tick2measure(m->tick());
2017-03-08 13:12:26 +01:00
Segment* lseg = lm->undoGetSegmentR(SegmentType::BarLine, rtick());
2016-02-17 14:54:23 +01:00
BarLine* lbl = toBarLine(lseg->element(0));
if (lbl) {
// already a barline here
if (lNewSpan > 0) {
// keep barline, but update span if necessary
if (lbl->span() != lNewSpan)
2018-03-27 15:36:00 +02:00
lbl->undoChangeProperty(Pid::BARLINE_SPAN, lNewSpan);
}
else {
// remove barline
lbl->unlink();
lbl->score()->undoRemoveElement(lbl);
}
}
else {
// new barline needed
2016-02-17 14:54:23 +01:00
lbl = toBarLine(linkedClone());
lbl->setSpan(lNewSpan);
lbl->setTrack(lstaff->idx() * VOICES);
lbl->setScore(lscore);
lbl->setParent(lseg);
lscore->undoAddElement(lbl);
}
}
}
}
}
2018-03-27 15:36:00 +02:00
undoChangeProperty(Pid::BARLINE_SPAN, newSpanStaff);
undoChangeProperty(Pid::BARLINE_SPAN_FROM, newSpanFrom);
undoChangeProperty(Pid::BARLINE_SPAN_FROM, newSpanTo);
return;
}
2012-11-11 01:50:57 +01:00
// if same as staff settings, do nothing
2016-12-23 12:05:18 +01:00
if (staff()->barLineSpan() == _spanStaff && staff()->barLineFrom() == _spanFrom && staff()->barLineTo() == _spanTo)
2012-05-26 14:26:10 +02:00
return;
2016-12-23 12:05:18 +01:00
// int idx1 = staffIdx();
if (_span != staff()->barLineSpan()) {
2012-10-14 00:35:11 +02:00
// if now bar lines span more staves
if (_span > staff()->barLineSpan()) {
int idx2 = idx1 + _span;
// set span 0 to all additional staves
2016-01-04 14:48:58 +01:00
for (int idx = idx1 + 1; idx < idx2; ++idx) {
// Mensurstrich special case:
// if line spans to top line of a stave AND current staff is
// the last spanned staff BUT NOT the last score staff
// keep its bar lines
// otherwise remove them
if (_spanTo > 0 || !(idx == idx2-1 && idx != score()->nstaves()-1)) {
Staff* staff = score()->staff(idx);
2018-03-27 15:36:00 +02:00
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN, 0);
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_FROM, 0);
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_TO, (staff->lines(tick())-1)*2);
}
2016-01-04 14:48:58 +01:00
}
2012-10-14 00:35:11 +02:00
}
// if now bar lines span fewer staves
else {
int idx1 = staffIdx() + _span;
int idx2 = staffIdx() + staff()->barLineSpan();
2012-11-11 01:50:57 +01:00
// set standard span for each no-longer-spanned staff
for (int idx = idx1; idx < idx2; ++idx) {
Staff* staff = score()->staff(idx);
2016-12-13 13:16:17 +01:00
int lines = staff->lines(tick());
2016-12-23 12:05:18 +01:00
int spanFrom = 0;
int spanTo = 0;
2018-03-27 15:36:00 +02:00
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN, 1);
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_FROM, spanFrom);
staff->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_TO, spanTo);
}
2012-10-14 00:35:11 +02:00
}
2012-05-26 14:26:10 +02:00
}
// update span for the staff the edited bar line belongs to
2018-03-27 15:36:00 +02:00
staff()->undoChangeProperty(Pid::STAFF_BARLINE_SPAN, _spanStaff);
staff()->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_FROM, _spanFrom);
staff()->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_TO, _spanTo);
2017-06-02 10:27:32 +02:00
#endif
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// editDrag
//---------------------------------------------------------
2017-03-31 13:03:15 +02:00
void BarLine::editDrag(EditData& ed)
2012-05-26 14:26:10 +02:00
{
2017-06-02 10:27:32 +02:00
BarLineEditData* bed = static_cast<BarLineEditData*>(ed.getData(this));
2016-12-13 13:16:17 +01:00
qreal lineDist = staff()->lineDistance(tick()) * spatium();
2016-12-23 12:05:18 +01:00
getY();
if (ed.curGrip == Grip::START) {
// Start grip moving is useless currently, so disable it
return;
#if 0
2015-04-10 04:39:14 +02:00
// min offset for top grip is line -1 (-2 for 1-line staves)
2012-10-14 00:35:11 +02:00
// max offset is 1 line above bottom grip or 1 below last staff line, whichever comes first
2016-12-13 13:16:17 +01:00
int lines = staff()->lines(tick());
2017-06-02 10:27:32 +02:00
qreal min = (-y1 - lines == 1) ? lineDist * 2 : lineDist;
qreal max = y2 - y1 - lineDist; // 1 line above bottom grip
qreal lastmax = (lines - _spanFrom/2) * lineDist; // 1 line below last staff line
if (lastmax < max)
2012-10-14 00:35:11 +02:00
max = lastmax;
// update yoff1 and bring it within limits
2017-06-02 10:27:32 +02:00
bed->yoff1 += ed.delta.y();
if (bed->yoff1 < min)
bed->yoff1 = min;
if (bed->yoff1 > max)
bed->yoff1 = max;
#endif
2012-10-14 00:35:11 +02:00
}
else {
// min for bottom grip is 1 line below top grip
const qreal min = y1 - y2 + lineDist;
// max is the bottom of the system
const System* system = segment() ? segment()->system() : nullptr;
const int st = staffIdx();
const qreal max = (system && st != -1) ? (system->height() - y2 - system->staff(st)->y()) : std::numeric_limits<qreal>::max();
2012-10-14 00:35:11 +02:00
// update yoff2 and bring it within limit
2017-06-02 10:27:32 +02:00
bed->yoff2 += ed.delta.y();
if (bed->yoff2 < min)
bed->yoff2 = min;
if (bed->yoff2 > max)
bed->yoff2 = max;
2012-10-14 00:35:11 +02:00
}
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// endEditDrag
2012-10-14 00:35:11 +02:00
// snap to nearest staff / staff line
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2017-06-02 10:27:32 +02:00
void BarLine::endEditDrag(EditData& ed)
2012-05-26 14:26:10 +02:00
{
2016-12-23 12:05:18 +01:00
getY();
2017-06-02 10:27:32 +02:00
BarLineEditData* bed = static_cast<BarLineEditData*>(ed.getData(this));
y1 += bed->yoff1;
y2 += bed->yoff2;
qreal ay0 = pagePos().y();
qreal ay2 = ay0 + y2; // absolute (page-relative) bar line bottom coord
int staffIdx1 = staffIdx();
2016-02-04 17:06:32 +01:00
System* syst = segment()->measure()->system();
qreal systTopY = syst->pagePos().y();
2012-10-14 00:35:11 +02:00
// determine new span value
2017-06-02 10:27:32 +02:00
int staffIdx2;
2012-10-14 00:35:11 +02:00
int numOfStaves = syst->staves()->size();
if (staffIdx1 + 1 >= numOfStaves)
// if initial staff is last staff, ending staff must be the same
2012-05-26 14:26:10 +02:00
staffIdx2 = staffIdx1;
2012-10-14 00:35:11 +02:00
2012-05-26 14:26:10 +02:00
else {
2012-10-14 00:35:11 +02:00
// if there are other staves after it, look for staff nearest to bar line bottom coord
qreal staff1TopY = syst->staff(staffIdx1)->y() + systTopY;
for (staffIdx2 = staffIdx1 + 1; staffIdx2 < numOfStaves; ++staffIdx2) {
// compute 1st staff height, absolute top Y of 2nd staff and height of blank between the staves
Staff * staff1 = score()->staff(staffIdx2-1);
2016-12-13 13:16:17 +01:00
qreal staff1Hght = (staff1->lines(tick())-1) * staff1->lineDistance(tick()) * spatium();
2012-10-14 00:35:11 +02:00
qreal staff2TopY = systTopY + syst->staff(staffIdx2)->y();
qreal blnkBtwnStaff = staff2TopY - staff1TopY - staff1Hght;
// if bar line bottom coord is above than mid-way of blank between staves...
if (ay2 < (staff1TopY + staff1Hght + blnkBtwnStaff * .5))
break; // ...staff 1 is ending staff
// if bar line is below, advance to next staff
staff1TopY = staff2TopY;
2012-05-26 14:26:10 +02:00
}
staffIdx2 -= 1;
}
2012-10-14 00:35:11 +02:00
// determine new spanFrom and spanTo values
int newSpanFrom, newSpanTo;
2016-12-23 12:05:18 +01:00
// Staff * staff2 = score()->staff(staffIdx2);
// int staff1lines = staff()->lines(tick());
// int staff2lines = staff2->lines(tick());
2016-12-23 12:05:18 +01:00
#if 0 // TODO
if (shiftDrag) { // if precision dragging
newSpanFrom = _spanFrom;
if (yoff1 != 0.0) {
// round bar line top coord to nearest line of 1st staff (in half line dist units)
2016-12-13 13:16:17 +01:00
newSpanFrom = ((int)floor(y1 / (staff()->lineDistance(tick()) * spatium()) + 0.5 )) * 2;
// min = 1 line dist above 1st staff line | max = 1 line dist below last staff line
2015-04-10 04:39:14 +02:00
// except for 1-line staves
int minFrom = staff1lines == 1 ? BARLINE_SPAN_1LINESTAFF_FROM : MIN_BARLINE_SPAN_FROMTO;
2015-04-10 04:39:14 +02:00
if (newSpanFrom < minFrom)
newSpanFrom = minFrom;
if (newSpanFrom > staff1lines * 2)
newSpanFrom = staff1lines * 2;
}
2012-10-14 00:35:11 +02:00
newSpanTo = _spanTo;
if (yoff2 != 0.0) {
// round bar line bottom coord to nearest line of 2nd staff (in half line dist units)
qreal staff2TopY = systTopY + syst->staff(staffIdx2)->y();
2016-12-13 13:16:17 +01:00
newSpanTo = ((int)floor( (ay2 - staff2TopY) / (staff2->lineDistance(tick()) * spatium()) + 0.5 )) * 2;
// min = 1 line dist above 1st staff line | max = 1 line dist below last staff line
int maxTo = staff2lines == 1 ? BARLINE_SPAN_1LINESTAFF_TO : staff2lines * 2;
if (newSpanTo < MIN_BARLINE_SPAN_FROMTO)
newSpanTo = MIN_BARLINE_SPAN_FROMTO;
2015-04-10 04:39:14 +02:00
if (newSpanTo > maxTo)
newSpanTo = maxTo;
}
2016-02-09 13:51:19 +01:00
}
2016-12-23 12:05:18 +01:00
#endif
// else { // if coarse dragging
{ // if coarse dragging
newSpanFrom = 0;
newSpanTo = 0;
}
2014-04-09 16:09:21 +02:00
2017-06-02 10:27:32 +02:00
bool localDrag = ed.control() || segment()->isBarLine();
if (localDrag) {
Segment* s = segment();
for (int staffIdx = staffIdx1; staffIdx < staffIdx2; ++staffIdx) {
BarLine* b = toBarLine(s->element(staffIdx * VOICES));
if (!b) {
b = toBarLine(linkedClone());
b->setSpanStaff(true);
b->setTrack(staffIdx * VOICES);
b->setScore(score());
b->setParent(s);
score()->undoAddElement(b);
}
2018-03-27 15:36:00 +02:00
b->undoChangeProperty(Pid::BARLINE_SPAN, true);
2017-06-02 10:27:32 +02:00
}
BarLine* b = toBarLine(s->element(staffIdx2 * VOICES));
if (b)
2018-03-27 15:36:00 +02:00
b->undoChangeProperty(Pid::BARLINE_SPAN, false);
2017-06-02 10:27:32 +02:00
}
else {
for (int staffIdx = staffIdx1; staffIdx < staffIdx2; ++staffIdx)
2018-03-27 15:36:00 +02:00
score()->staff(staffIdx)->undoChangeProperty(Pid::STAFF_BARLINE_SPAN, true);
score()->staff(staffIdx2)->undoChangeProperty(Pid::STAFF_BARLINE_SPAN, false);
staff()->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_FROM, newSpanFrom);
staff()->undoChangeProperty(Pid::STAFF_BARLINE_SPAN_TO, newSpanTo);
2012-10-14 00:35:11 +02:00
}
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
2012-08-02 18:33:43 +02:00
// layoutWidth
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
2017-08-04 12:05:30 +02:00
qreal BarLine::layoutWidth(Score* score, BarLineType type)
2012-05-26 14:26:10 +02:00
{
2017-03-20 18:24:16 +01:00
qreal dotwidth = score->scoreFont()->width(SymId::repeatDot, 1.0);
2017-03-20 13:36:46 +01:00
qreal w {0.0};
switch (type) {
case BarLineType::DOUBLE:
2018-03-27 15:36:00 +02:00
w = score->styleP(Sid::doubleBarWidth) + score->styleP(Sid::doubleBarDistance);
2012-05-26 14:26:10 +02:00
break;
2019-04-06 07:54:38 +02:00
case BarLineType::END_START_REPEAT:
w = score->styleP(Sid::endBarDistance) * 2
+ score->styleP(Sid::repeatBarlineDotSeparation) * 2
+ dotwidth;
break;
case BarLineType::START_REPEAT:
case BarLineType::END_REPEAT:
2018-03-27 15:36:00 +02:00
w = score->styleP(Sid::endBarWidth) * .5
+ score->styleP(Sid::endBarDistance)
+ score->styleP(Sid::repeatBarlineDotSeparation)
2017-08-04 12:05:30 +02:00
+ dotwidth * .5;
2012-05-26 14:26:10 +02:00
break;
case BarLineType::END:
2018-03-27 15:36:00 +02:00
w = (score->styleP(Sid::endBarWidth) + score->styleP(Sid::barWidth)) * .5
+ score->styleP(Sid::endBarDistance);
2012-05-26 14:26:10 +02:00
break;
case BarLineType::BROKEN:
case BarLineType::NORMAL:
case BarLineType::DOTTED:
2018-03-27 15:36:00 +02:00
w = score->styleP(Sid::barWidth);
2012-05-26 14:26:10 +02:00
break;
}
2017-08-04 12:05:30 +02:00
return w;
2012-08-02 18:33:43 +02:00
}
2019-04-28 22:00:10 +02:00
//---------------------------------------------------------
// layoutRect
//---------------------------------------------------------
QRectF BarLine::layoutRect() const
{
QRectF bb = bbox();
if (staff()) {
// actual height may include span to next staff
// but this should not be included in shapes or skylines
qreal sp = spatium();
int span = staff()->lines(tick()) - 1;
int sFrom;
int sTo;
if (span == 0 && _spanTo == 0) {
sFrom = BARLINE_SPAN_1LINESTAFF_FROM;
sTo = _spanStaff ? 0 : BARLINE_SPAN_1LINESTAFF_TO;
}
else {
sFrom = _spanFrom;
sTo = _spanStaff ? 0 : _spanTo;
}
qreal y = sp * sFrom * 0.5;
qreal h = sp * (span + (sTo - sFrom) * 0.5);
if (score()->styleB(Sid::repeatBarTips)) {
switch (barLineType()) {
case BarLineType::START_REPEAT:
case BarLineType::END_REPEAT:
case BarLineType::END_START_REPEAT: {
if (isTop()) {
qreal top = symBbox(SymId::bracketTop).height();
y -= top;
h += top;
}
if (isBottom()) {
qreal bottom = symBbox(SymId::bracketBottom).height();
h += bottom;
}
}
default:
break;
}
}
bb.setY(y);
bb.setHeight(h);
}
return bb;
}
2012-08-02 18:33:43 +02:00
//---------------------------------------------------------
// layout
//---------------------------------------------------------
void BarLine::layout()
{
2017-03-20 18:24:16 +01:00
setPos(QPointF());
// barlines hidden on this staff
if (staff() && segment()) {
if ((!staff()->staffType(tick())->showBarlines() && segment()->segmentType() == SegmentType::EndBarLine)
|| (staff()->hideSystemBarLine() && segment()->segmentType() == SegmentType::BeginBarLine)) {
setbbox(QRectF());
return;
}
}
2018-03-27 15:36:00 +02:00
setMag(score()->styleB(Sid::scaleBarlines) && staff() ? staff()->mag(tick()) : 1.0);
2016-12-29 15:11:28 +01:00
qreal _spatium = spatium();
y1 = _spatium * .5 * _spanFrom;
y2 = _spatium * .5 * (8.0 + _spanTo);
2017-08-04 12:05:30 +02:00
qreal w = layoutWidth(score(), barLineType()) * mag();
QRectF r(0.0, y1, w, y2 - y1);
2016-12-29 15:11:28 +01:00
2018-03-27 15:36:00 +02:00
if (score()->styleB(Sid::repeatBarTips)) {
2016-12-29 15:11:28 +01:00
switch (barLineType()) {
case BarLineType::START_REPEAT:
r |= symBbox(SymId::bracketTop).translated(0, y1);
2017-03-20 18:24:16 +01:00
// r |= symBbox(SymId::bracketBottom).translated(0, y2);
2016-12-29 15:11:28 +01:00
break;
2017-03-20 18:24:16 +01:00
case BarLineType::END_REPEAT: {
2019-04-06 07:54:38 +02:00
qreal w1 = 0.0; //symBbox(SymId::reversedBracketTop).width();
2017-03-20 18:24:16 +01:00
r |= symBbox(SymId::reversedBracketTop).translated(-w1, y1);
// r |= symBbox(SymId::reversedBracketBottom).translated(0, y2);
}
2016-12-29 15:11:28 +01:00
break;
2019-04-06 07:54:38 +02:00
case BarLineType::END_START_REPEAT: {
qreal w1 = 0.0; //symBbox(SymId::reversedBracketTop).width();
r |= symBbox(SymId::reversedBracketTop).translated(-w1, y1);
r |= symBbox(SymId::bracketTop).translated(0, y1);
// r |= symBbox(SymId::reversedBracketBottom).translated(0, y2);
}
break;
2016-12-29 15:11:28 +01:00
default:
break;
2012-05-26 14:26:10 +02:00
}
}
2016-12-29 15:11:28 +01:00
setbbox(r);
2016-01-04 14:48:58 +01:00
for (Element* e : _el) {
2012-05-26 14:26:10 +02:00
e->layout();
2016-02-17 14:54:23 +01:00
if (e->isArticulation()) {
2016-12-23 12:05:18 +01:00
Articulation* a = toArticulation(e);
Direction dir = a->direction();
qreal distance = 0.5 * spatium();
qreal x = width() * .5;
2016-03-02 13:20:19 +01:00
if (dir == Direction::DOWN) {
2012-05-26 14:26:10 +02:00
qreal botY = y2 + distance;
a->setPos(QPointF(x, botY));
}
else {
qreal topY = y1 - distance;
a->setPos(QPointF(x, topY));
}
2012-05-26 14:26:10 +02:00
}
}
}
2016-12-23 12:05:18 +01:00
//---------------------------------------------------------
// layout2
// called after system layout; set vertical dimensions
//---------------------------------------------------------
void BarLine::layout2()
{
// barlines hidden on this staff
if (staff() && segment()) {
if ((!staff()->staffType(tick())->showBarlines() && segment()->segmentType() == SegmentType::EndBarLine)
|| (staff()->hideSystemBarLine() && segment()->segmentType() == SegmentType::BeginBarLine)) {
setbbox(QRectF());
return;
}
}
2016-12-23 12:05:18 +01:00
getY();
2017-03-20 13:36:46 +01:00
bbox().setTop(y1);
bbox().setBottom(y2);
2016-12-23 12:05:18 +01:00
2018-03-27 15:36:00 +02:00
if (score()->styleB(Sid::repeatBarTips)) {
2016-12-29 15:11:28 +01:00
switch (barLineType()) {
case BarLineType::START_REPEAT:
2017-03-20 13:36:46 +01:00
bbox() |= symBbox(SymId::bracketTop).translated(0, y1);
bbox() |= symBbox(SymId::bracketBottom).translated(0, y2);
2016-12-29 15:11:28 +01:00
break;
case BarLineType::END_REPEAT:
{
2019-04-06 07:54:38 +02:00
qreal w1 = 0.0; //symBbox(SymId::reversedBracketTop).width();
2017-03-20 18:24:16 +01:00
bbox() |= symBbox(SymId::reversedBracketTop).translated(-w1, y1);
bbox() |= symBbox(SymId::reversedBracketBottom).translated(-w1, y2);
2016-12-29 15:11:28 +01:00
break;
}
2019-04-06 07:54:38 +02:00
case BarLineType::END_START_REPEAT:
{
qreal w1 = 0.0; //symBbox(SymId::reversedBracketTop).width();
bbox() |= symBbox(SymId::reversedBracketTop).translated(-w1, y1);
bbox() |= symBbox(SymId::reversedBracketBottom).translated(-w1, y2);
bbox() |= symBbox(SymId::bracketTop).translated(0, y1);
bbox() |= symBbox(SymId::bracketBottom).translated(0, y2);
break;
}
2016-12-29 15:11:28 +01:00
default:
break;
2016-12-23 12:05:18 +01:00
}
}
2017-03-20 13:36:46 +01:00
}
//---------------------------------------------------------
// shape
//---------------------------------------------------------
Shape BarLine::shape() const
{
Shape shape;
#ifndef NDEBUG
shape.add(bbox(), name());
#else
2017-03-20 13:36:46 +01:00
shape.add(bbox());
#endif
2017-03-20 13:36:46 +01:00
return shape;
2016-12-23 12:05:18 +01:00
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// scanElements
//---------------------------------------------------------
void BarLine::scanElements(void* data, void (*func)(void*, Element*), bool all)
{
// if no width (staff has bar lines turned off) and not all requested, do nothing
if (width() == 0.0 && !all)
return;
2012-05-26 14:26:10 +02:00
func(data, this);
2016-02-04 17:06:32 +01:00
for (Element* e : _el)
2012-05-26 14:26:10 +02:00
e->scanElements(data, func, all);
}
//---------------------------------------------------------
// setTrack
//---------------------------------------------------------
void BarLine::setTrack(int t)
{
Element::setTrack(t);
for (Element* e : _el)
e->setTrack(t);
}
//---------------------------------------------------------
// setScore
//---------------------------------------------------------
void BarLine::setScore(Score* s)
{
Element::setScore(s);
for (Element* e : _el)
e->setScore(s);
}
2012-05-26 14:26:10 +02:00
//---------------------------------------------------------
// add
//---------------------------------------------------------
void BarLine::add(Element* e)
{
2014-05-30 13:35:44 +02:00
e->setParent(this);
2016-02-04 17:06:32 +01:00
switch (e->type()) {
2017-01-18 14:16:33 +01:00
case ElementType::ARTICULATION:
case ElementType::SYMBOL:
case ElementType::IMAGE:
2013-03-25 16:27:20 +01:00
_el.push_back(e);
2012-05-26 14:26:10 +02:00
setGenerated(false);
break;
default:
qDebug("BarLine::add() not impl. %s", e->name());
delete e;
2012-05-26 14:26:10 +02:00
break;
}
}
//---------------------------------------------------------
// remove
//---------------------------------------------------------
void BarLine::remove(Element* e)
{
switch(e->type()) {
2017-01-18 14:16:33 +01:00
case ElementType::ARTICULATION:
case ElementType::SYMBOL:
case ElementType::IMAGE:
2012-05-26 14:26:10 +02:00
if (!_el.remove(e))
qDebug("BarLine::remove(): cannot find %s", e->name());
2012-05-26 14:26:10 +02:00
break;
default:
qDebug("BarLine::remove() not impl. %s", e->name());
2012-05-26 14:26:10 +02:00
break;
}
}
//---------------------------------------------------------
// getProperty
//---------------------------------------------------------
2018-03-27 15:36:00 +02:00
QVariant BarLine::getProperty(Pid id) const
2012-05-26 14:26:10 +02:00
{
switch (id) {
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_TYPE:
2016-02-10 13:40:34 +01:00
return QVariant::fromValue(_barLineType);
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN:
2016-12-23 12:05:18 +01:00
return spanStaff();
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_FROM:
2016-12-23 12:05:18 +01:00
return int(spanFrom());
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_TO:
2016-12-23 12:05:18 +01:00
return int(spanTo());
default:
break;
}
2012-08-10 17:01:35 +02:00
return Element::getProperty(id);
2012-05-26 14:26:10 +02:00
}
//---------------------------------------------------------
// setProperty
//---------------------------------------------------------
2018-03-27 15:36:00 +02:00
bool BarLine::setProperty(Pid id, const QVariant& v)
2012-05-26 14:26:10 +02:00
{
2016-02-04 17:06:32 +01:00
switch (id) {
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_TYPE:
2016-02-10 13:40:34 +01:00
setBarLineType(v.value<BarLineType>());
break;
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN:
2016-12-23 12:05:18 +01:00
setSpanStaff(v.toBool());
break;
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_FROM:
setSpanFrom(v.toInt());
break;
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_TO:
setSpanTo(v.toInt());
break;
default:
return Element::setProperty(id, v);
}
2016-02-09 13:51:19 +01:00
setGenerated(false);
triggerLayout();
2012-08-10 17:01:35 +02:00
return true;
2012-05-26 14:26:10 +02:00
}
2012-10-17 20:22:24 +02:00
2018-01-04 12:41:42 +01:00
//---------------------------------------------------------
// undoChangeProperty
//---------------------------------------------------------
2018-03-27 15:36:00 +02:00
void BarLine::undoChangeProperty(Pid id, const QVariant& v, PropertyFlags ps)
2018-01-04 12:41:42 +01:00
{
2018-03-27 15:36:00 +02:00
if (id == Pid::BARLINE_TYPE && segment()) {
const BarLine* bl = this;
BarLineType blType = v.value<BarLineType>();
if (blType == BarLineType::START_REPEAT) { // change next measures endBarLine
if (bl->measure()->nextMeasure())
bl = bl->measure()->nextMeasure()->endBarLine();
else
bl = 0;
}
if (bl)
undoChangeBarLineType(const_cast<BarLine*>(bl), v.value<BarLineType>(), true);
}
2018-01-04 12:41:42 +01:00
else
ScoreElement::undoChangeProperty(id, v, ps);
}
//---------------------------------------------------------
// propertyDefault
//---------------------------------------------------------
2018-03-27 15:36:00 +02:00
QVariant BarLine::propertyDefault(Pid propertyId) const
{
2016-01-04 14:48:58 +01:00
switch (propertyId) {
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_TYPE:
2018-07-23 12:14:52 +02:00
// dynamic default values are a bad idea: writing to xml the value maybe ommited resulting in
// wrong values on read (as the default may be different on read)
// if (segment() && segment()->measure() && !segment()->measure()->nextMeasure())
// return QVariant::fromValue(BarLineType::END);
2016-08-24 09:57:24 +02:00
return QVariant::fromValue(BarLineType::NORMAL);
2016-01-04 14:48:58 +01:00
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN:
2016-12-23 12:05:18 +01:00
return staff() ? staff()->barLineSpan() : false;
2016-02-09 13:51:19 +01:00
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_FROM:
2016-12-18 14:31:13 +01:00
return staff() ? staff()->barLineFrom() : 0;
2016-02-09 13:51:19 +01:00
2018-03-27 15:36:00 +02:00
case Pid::BARLINE_SPAN_TO:
2016-12-18 14:31:13 +01:00
return staff() ? staff()->barLineTo() : 0;
2016-02-09 13:51:19 +01:00
default:
break;
}
return Element::propertyDefault(propertyId);
}
2013-05-13 18:49:17 +02:00
2019-05-31 11:47:18 +02:00
//---------------------------------------------------------
// propertyId
//---------------------------------------------------------
Pid BarLine::propertyId(const QStringRef& name) const
{
if (name == "subtype")
return Pid::BARLINE_TYPE;
return Element::propertyId(name);
}
//---------------------------------------------------------
// nextSegmentElement
//---------------------------------------------------------
Element* BarLine::nextSegmentElement()
{
2016-02-04 17:06:32 +01:00
return segment()->firstInNextSegments(score()->inputState().prevTrack() / VOICES);
}
//---------------------------------------------------------
// prevSegmentElement
//---------------------------------------------------------
Element* BarLine::prevSegmentElement()
{
2016-02-04 17:06:32 +01:00
return segment()->lastInPrevSegments(score()->inputState().prevTrack() / VOICES);
}
//---------------------------------------------------------
// accessibleInfo
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
QString BarLine::accessibleInfo() const
{
2016-02-04 17:06:32 +01:00
return QString("%1: %2").arg(Element::accessibleInfo()).arg(BarLine::userTypeName(barLineType()));
}
//---------------------------------------------------------
// accessibleExtraInfo
//---------------------------------------------------------
2016-02-04 17:06:32 +01:00
QString BarLine::accessibleExtraInfo() const
{
2016-02-04 17:06:32 +01:00
Segment* seg = segment();
QString rez;
2016-02-04 17:06:32 +01:00
for (const Element* e : *el()) {
if (!score()->selectionFilter().canSelect(e))
continue;
rez = QString("%1 %2").arg(rez).arg(e->screenReaderInfo());
}
for (const Element* e : seg->annotations()) {
if (!score()->selectionFilter().canSelect(e))
continue;
if (e->track() == track())
rez = QString("%1 %2").arg(rez).arg(e->screenReaderInfo());
2016-02-04 17:06:32 +01:00
}
Measure* m = seg->measure();
2016-02-09 13:51:19 +01:00
if (m) { // always true?
2016-02-04 17:06:32 +01:00
//jumps
for (const Element* e : m->el()) {
if (!score()->selectionFilter().canSelect(e)) continue;
2017-01-18 14:16:33 +01:00
if (e->type() == ElementType::JUMP)
2016-02-04 17:06:32 +01:00
rez= QString("%1 %2").arg(rez).arg(e->screenReaderInfo());
2017-01-18 14:16:33 +01:00
if (e->type() == ElementType::MARKER) {
This commit contains changes required for MuseScore to compile under MSVC with no warnings. This commit contains changes required for MuseScore to compile under MSVC with no warnings. MuseScore is being compiled with the /W4 setting (warning level 4), which is similar to -wall -wextra on clang. This generates lots of warnings on MSVC, mainly for non-standard constructs and for constructs which might be bugs or might lead to bugs. Most warnings are in the following categories: - Name hiding: a variable hides a variable with the same name on a larger scope (or a field, or a function parameter). This can easily lead to bugs, and it is a best practice to avoid hiding variable names (see recommendation ES.12 in the C++ Core Guidelines by Stroustrop & Sutter (http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Res-reuse : ES.12: Do not reuse names in nested scopes) - Narrowing conversion: a numeric conversion results in loss of significant digits (for example, double -> float). The general recommendation is to use a cast to indicate this is designed behaviour. - Unreachable code: in several instances, there is unreachable code. The unreachable code is commented out. - (Potentially) uninitialized local variable. Just initialized the vars. - foreach(,) -> for(:): this does not generate a warning per-se (only a few of these generate warnings due to name hiding), but changed in keeping with "MuseScore Coding Rules" (https://musescore.org/en/handbook/musescore-coding-rules#Loops), which tells explicitly "Use C++11's "for" instead of Qt's "foreach":" ... "If you happen to be fixing some code and see a "foreach", please change that loop into a "for"." Most changes are in the categories indicated above. The next listing shows detailed changes for files which are *not* of the aforementioned types. - all.h: Disable warning C4127 (conditional expression is constant - generated in Qt header file qvector.h) - awl/aslider.h: unreachable code. - awl/knob.cpp: name hiding - awl/mslider.cpp: name hiding - awl/slider.cpp: name hiding - bww2mxml/parser.cpp: name hiding - effects/compressor/compressor.cpp: narrowing conversion - effects/zita1/zitagui.cpp: name hiding - fluid/fluid.cpp: foreach replacement. Name hiding. - fluid/mod.cpp: name hiding. - fluid/sfont.cpp: foreach replacement. Name hiding. Initialize vars. - fluid/voice.cpp: Name hiding. - libmscore/accidental.cpp: Name hiding. - libmscore/ambitus.cpp: Initialize vars. - libmscore/barline.cpp: Name hiding. Unreachable code. - libmscore/beam.cpp: Name hiding. - libmscore/chordrest.cpp: Unreachable code. - libmscore/scorefile.cpp: Name hiding. - manual/genManual.cpp: Name hiding. foreach replacement. - midi/midifile.cpp: Name hiding. Unreachable code. - omr/importpdf.cpp: Name hiding. foreach replacement. - omr/omr.cpp: Name hiding. foreach replacement. - omr/omrpage.cpp: Name hiding. foreach replacement. - omr/omrview.cpp: Name hiding. foreach replacement. - synthesizer/event.cpp: Unreachable code. - zerberus\channel.cpp: Narrowing conversion. - zerberus\instrument.cpp: Name hiding. - zerberus\sfz.cpp: Name hiding. - zerberus\voice.h: Suppress warning C4201: "nonstandard extension used: nameless struct/union" - zerberus\zerberus.cpp: Name hiding. Unreferenced parameter. - zerberus\zerberusgui.cpp: Name hiding.
2018-05-03 03:04:08 +02:00
const Marker* m1 = toMarker(e);
if (m1->markerType() == Marker::Type::FINE)
2016-02-04 17:06:32 +01:00
rez = QString("%1 %2").arg(rez).arg(e->screenReaderInfo());
}
2016-02-04 17:06:32 +01:00
}
//markers
Measure* nextM = m->nextMeasureMM();
if (nextM) {
for (const Element* e : nextM->el()) {
if (!score()->selectionFilter().canSelect(e))
continue;
if (e->isMarker()) {
2016-02-17 14:54:23 +01:00
if (toMarker(e)->markerType() == Marker::Type::FINE)
2016-02-04 17:06:32 +01:00
continue; //added above^
rez = QString("%1 %2").arg(rez).arg(e->screenReaderInfo());
}
}
}
}
Fraction tick = seg->tick();
2016-02-04 17:06:32 +01:00
auto spanners = score()->spannerMap().findOverlapping(tick.ticks(), tick.ticks());
2016-02-04 17:06:32 +01:00
for (auto interval : spanners) {
Spanner* s = interval.value;
if (!score()->selectionFilter().canSelect(s))
continue;
2017-01-18 14:16:33 +01:00
if (s->type() == ElementType::VOLTA) {
2016-02-04 17:06:32 +01:00
if (s->tick() == tick)
rez = QObject::tr("%1 Start of %2").arg(rez).arg(s->screenReaderInfo());
2016-02-04 17:06:32 +01:00
if (s->tick2() == tick)
rez = QObject::tr("%1 End of %2").arg(rez).arg(s->screenReaderInfo());
2016-02-04 17:06:32 +01:00
}
}
return rez;
}
2013-05-13 18:49:17 +02:00
}