misc. updates to layout

This commit is contained in:
ws 2016-03-18 09:29:16 +01:00
parent f281db5f22
commit 3f1aa2ed1f
40 changed files with 429 additions and 425 deletions

View file

@ -66,10 +66,8 @@ include (CreatePrecompiledHeader)
# for debugging the make system uncomment next line:
# set(CMAKE_VERBOSE_MAKEFILE ON)
set (CMAKE_AUTOMOC TRUE)
set(MSCORE_UNSTABLE TRUE) # mark as unstable
set (CMAKE_AUTOMOC TRUE)
set(MSCORE_UNSTABLE TRUE) # mark as unstable
set(USE_SSE TRUE)
set(SCRIPT_INTERFACE TRUE)
@ -158,7 +156,7 @@ else (APPLE)
set(CMAKE_EXE_LINKER_FLAGS "-Wl,--large-address-aware")
else (MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-std=c++11 -fPIC -g")
set(CMAKE_CXX_FLAGS_RELEASE "-std=c++11 -fPIC -O2 -DNDEBUG -DQT_NO_DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-std=c++11 -fPIC -O2 -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT")
endif (MINGW)
endif(APPLE)

3
all.h
View file

@ -31,10 +31,9 @@
#include <math.h>
#include <QtGui>
#include <QLoggingCategory>
#include <QModelIndex>
// #include <QWebView>
// #include <QWebFrame>
#include <QWebEngineView>
#include <QtXml>

View file

@ -83,14 +83,14 @@ namespace Ms {
void CmdState::reset()
{
refresh = QRectF(); ///< area to update, canvas coordinates
// refresh = QRectF(); ///< area to update, canvas coordinates
layoutFlags = LayoutFlag::NO_FLAGS;
_updateMode = UpdateMode::DoNothing;
_playNote = false; ///< play selected note after command
_playChord = false; ///< play whole chord for the selected note
// _playNote = false; ///< play selected note after command
// _playChord = false; ///< play whole chord for the selected note
_excerptsChanged = false;
_instrumentsChanged = false;
_selectionChanged = false;
// _selectionChanged = false;
_startTick = -1;
_endTick = -1;
}
@ -107,7 +107,7 @@ void CmdState::setTick(int t)
_startTick = t;
if (_endTick == -1 || t > _endTick)
_endTick = t;
setUpdateMode(UpdateMode::LayoutTick);
setUpdateMode(UpdateMode::LayoutRange);
}
//---------------------------------------------------------
@ -131,7 +131,7 @@ void Score::startCmd()
if (MScore::debugMode)
qDebug("===startCmd()");
_cmdState.reset();
cmdState().reset();
// Start collecting low-level undo operations for a
// user-visible undo action.
@ -155,7 +155,7 @@ void Score::endCmd(bool rollback)
{
if (!undoStack()->active()) {
qDebug("Score::endCmd(): no cmd active");
end();
update();
return;
}
@ -164,22 +164,49 @@ void Score::endCmd(bool rollback)
undoStack()->current()->unwind();
}
// printf("Score::endCmd state %d tick %d %d\n", int(_cmdState.updateMode()), _cmdState.startTick(), _cmdState.endTick());
update();
switch (_cmdState.updateMode()) {
case UpdateMode::DoNothing:
case UpdateMode::Update:
case UpdateMode::UpdateAll:
break;
case UpdateMode::LayoutTick:
doLayoutRange(_cmdState.startTick(), _cmdState.endTick());
setUpdateAll();
break;
case UpdateMode::LayoutAll:
doLayout();
setUpdateAll();
setUpdateAll();
break;
if (MScore::debugMode)
qDebug("===endCmd() %d", undoStack()->current()->childCount());
bool noUndo = undoStack()->current()->childCount() <= 1; // nothing to undo?
undoStack()->endMacro(noUndo);
if (dirty()) {
masterScore()->_playlistDirty = true; // TODO: flag individual operations
masterScore()->_autosaveDirty = true;
}
MuseScoreCore::mscoreCore->endCmd();
}
//---------------------------------------------------------
// update
// layout & update
//---------------------------------------------------------
void Score::update()
{
CmdState& cs = cmdState();
if (cs.layoutAll()) {
for (Score* s : scoreList())
s->doLayout();
}
else if (cs.layoutRange()) {
for (Score* s : scoreList())
s->doLayoutRange(cs.startTick(), cs.endTick());
}
else if (cs.updateAll()) {
for (Score* s : scoreList()) {
for (MuseScoreView* v : s->viewer)
v->updateAll();
}
}
else if (cs.updateRange()) {
// updateRange updates only current score
qreal d = spatium() * .5;
_updateState.refresh.adjust(-d, -d, 2 * d, 2 * d);
for (MuseScoreView* v : viewer)
v->dataChanged(_updateState.refresh);
_updateState.refresh = QRectF();
}
const InputState& is = inputState();
@ -190,77 +217,7 @@ void Score::endCmd(bool rollback)
emit playlistChanged();
_playlistDirty = false;
}
if (MScore::debugMode)
qDebug("===endCmd() %d", undoStack()->current()->childCount());
bool noUndo = undoStack()->current()->childCount() <= 1; // nothing to undo?
undoStack()->endMacro(noUndo);
end(); // DEBUG
if (dirty()) {
masterScore()->_playlistDirty = true; // TODO: flag individual operations
masterScore()->_autosaveDirty = true;
}
MuseScoreCore::mscoreCore->endCmd();
}
//---------------------------------------------------------
// end
/// Update the redraw area.
//---------------------------------------------------------
void Score::end()
{
for (Score* s : scoreList())
s->end1();
}
//---------------------------------------------------------
// update
// layout & update
//---------------------------------------------------------
void Score::update()
{
for (Score* s : scoreList()) {
switch (s->_cmdState.updateMode()) {
case UpdateMode::DoNothing:
case UpdateMode::Update:
case UpdateMode::UpdateAll:
break;
case UpdateMode::LayoutTick:
s->doLayoutRange(_cmdState.startTick(), _cmdState.endTick());
s->setUpdateAll();
break;
case UpdateMode::LayoutAll:
s->doLayout();
s->setUpdateAll();
s->setUpdateAll();
break;
}
if (s != this)
s->deselectAll();
s->end1();
}
}
//---------------------------------------------------------
// end1
//---------------------------------------------------------
void Score::end1()
{
if (_cmdState.updateAll()) {
for (MuseScoreView* v : viewer)
v->updateAll();
}
else {
// update a little more:
qreal d = spatium() * .5;
_cmdState.refresh.adjust(-d, -d, 2 * d, 2 * d);
for (MuseScoreView* v : viewer)
v->dataChanged(_cmdState.refresh);
}
cmdState().reset();
}
//---------------------------------------------------------
@ -270,23 +227,8 @@ void Score::end1()
void Score::endUndoRedo()
{
update();
updateSelection();
for (Score* score : scoreList()) {
if (score->_cmdState.layoutAll()) {
score->masterScore()->setUndoRedo(true);
score->doLayout();
score->masterScore()->setUndoRedo(false);
score->setUpdateAll();
}
const InputState& is = score->inputState();
if (is.noteEntryMode() && is.segment())
score->setPlayPos(is.segment()->tick());
if (_playlistDirty) {
emit playlistChanged();
_playlistDirty = false;
}
}
end();
}
//---------------------------------------------------------
@ -515,7 +457,7 @@ void Score::cmdAddInterval(int val, const std::vector<Note*>& nl)
note->setPitch(npitch, ntpc1, ntpc2);
undoAddElement(note);
_cmdState._playNote = true;
setPlayNote(true);
select(note, SelectType::SINGLE, 0);
}
@ -642,7 +584,7 @@ Segment* Score::setNoteRest(Segment* segment, int track, NoteVal nval, Fraction
undoAddCR(ncr, measure, tick);
if (addTie)
undoAddElement(addTie);
_cmdState._playNote = true;
setPlayNote(true);
segment = ncr->segment();
tick += ncr->actualTicks();
}
@ -1432,7 +1374,7 @@ void Score::upDown(bool up, UpDownMode mode)
}
// play new note with velocity 80 for 0.3 sec:
_cmdState._playNote = true;
setPlayNote(true);
}
_selection.clear();
@ -1932,7 +1874,7 @@ Element* Score::move(const QString& cmd)
// if chord, go to topmost note
if (trg->type() == Element::Type::CHORD)
trg = static_cast<Chord*>(trg)->upNote();
_cmdState._playNote = true;
setPlayNote(true);
select(trg, SelectType::SINGLE, 0);
return trg;
}
@ -2048,7 +1990,7 @@ Element* Score::move(const QString& cmd)
if (el) {
if (el->type() == Element::Type::CHORD)
el = static_cast<Chord*>(el)->upNote(); // originally downNote
_cmdState._playNote = true;
setPlayNote(true);
if (noteEntryMode()) {
// if cursor moved into a gap, selection cannot follow
// only select & play el if it was not already selected (does not normally happen)
@ -2056,7 +1998,7 @@ Element* Score::move(const QString& cmd)
if (cr || !el->selected())
select(el, SelectType::SINGLE, 0);
else
_cmdState._playNote = false;
setPlayNote(false);
for (MuseScoreView* view : viewer)
view->moveCursor();
}

View file

@ -359,8 +359,8 @@ Note* Score::addNote(Chord* chord, NoteVal& noteVal)
note->setTrack(chord->track());
note->setNval(noteVal);
undoAddElement(note);
_cmdState._playNote = true;
_cmdState._playChord = true;
setPlayNote(true);
setPlayChord(true);
select(note, SelectType::SINGLE, 0);
if (!chord->staff()->isTabStaff())
_is.moveToNextInputPos();
@ -1393,8 +1393,8 @@ void Score::repitchNote(const Position& p, bool replace)
}
// add new note to chord
undoAddElement(note);
_cmdState._playNote = true;
_cmdState._playChord = true;
setPlayNote(true);
setPlayChord(true);
// recreate tie forward if there is a note to tie to
// one-sided ties will not be recreated
if (firstTiedNote) {
@ -2599,7 +2599,7 @@ void Score::colorItem(Element* element)
if (e->color() != c) {
undoChangeProperty(e, P_ID::COLOR, c);
e->setGenerated(false);
_cmdState.refresh |= e->abbox();
addRefresh(e->abbox());
if (e->type() == Element::Type::BAR_LINE) {
// Element* ep = e->parent();
// if (ep->type() == Element::Type::SEGMENT && static_cast<Segment*>(ep)->segmentType() == Segment::Type::EndBarLine) {

View file

@ -454,7 +454,7 @@ class Element : public QObject, public ScoreElement {
// debug functions
virtual void dump() const;
const char* name() const;
virtual const char* name() const override;
virtual Q_INVOKABLE QString subtypeName() const;
//@ Returns the human-readable name of the element type
virtual Q_INVOKABLE QString userName() const;

View file

@ -1289,8 +1289,8 @@ void Score::addSystemHeader(Measure* m, bool isFirstSystem)
for (Segment* seg = m->first(); seg; seg = seg->next()) {
// search only up to the first ChordRest/StartRepeatBarLine
// if (seg->isType(Segment::Type::ChordRest | Segment::Type::StartRepeatBarLine))
// break;
if (seg->isType(Segment::Type::ChordRest | Segment::Type::StartRepeatBarLine))
break;
Element* el = seg->element(strack);
if (!el)
continue;
@ -1331,7 +1331,7 @@ void Score::addSystemHeader(Measure* m, bool isFirstSystem)
keysig->segment()->createShape(staffIdx);
}
if (isFirstSystem || styleB(StyleIdx::genClef) || staff->clef(tick) != staff->clef(tick-1)) {
if (isFirstSystem || styleB(StyleIdx::genClef)) {
ClefTypeList cl = staff->clefType(tick);
if (!clef) {
//
@ -1349,7 +1349,7 @@ void Score::addSystemHeader(Measure* m, bool isFirstSystem)
clef->layout();
s->createShape(staffIdx);
}
else if (clef->generated()) {
else {
if (cl != clef->clefTypeList()) {
undo(new ChangeClefType(clef, cl._concertClef, cl._transposingClef));
clef->layout();
@ -1358,9 +1358,10 @@ void Score::addSystemHeader(Measure* m, bool isFirstSystem)
}
}
else {
if (clef && clef->generated()) {
if (clef) {
undo(new RemoveElement(clef));
clef->segment()->createShape(staffIdx);
if (clef->segment())
clef->segment()->createShape(staffIdx);
}
}
++staffIdx;
@ -2108,9 +2109,11 @@ qreal Score::computeMinWidth(Segment* s, bool isFirstMeasureInSystem)
if (ns) {
w = ss->minHorizontalDistance(ns);
#if 1
// look back for collisions with previous segments
#if 0
int n = 0;
// this is time consuming (ca. +5%) and probably requires more optimization
int n = 1;
for (Segment* ps = ss;;) {
qreal ww;
if (ps == s)
@ -2124,13 +2127,15 @@ qreal Score::computeMinWidth(Segment* s, bool isFirstMeasureInSystem)
if (ww > w) {
// overlap !
// distribute extra space between segments ps - ss;
#if 0
printf("overlap %s - %s %d - %d n=%d +%f\n", ps->subTypeName(), ns->subTypeName(), ss->tick(), ns->tick(), n, ww-w);
// only ChordRest segments get more space
// TODO: is there a special case n == 0 ?
// printf("overlap %s(%d) - %s(%d) n=%d +%f\n", ps->subTypeName(), ps->tick(), ns->subTypeName(), ns->tick(), n, ww-w);
qreal d = (ww - w) / n;
qreal xx = ps->x();
for (Segment* s = ps; s != ss;) {
Segment* ns = s->next();
qreal ww = s->width();
qreal ww = s->width();
if (s->isChordRestType()) {
ww += d;
s->setWidth(ww);
@ -2138,10 +2143,9 @@ printf("overlap %s - %s %d - %d n=%d +%f\n", ps->subTypeName(), ns->subTypeName
xx += ww;
ns->rxpos() = xx;
s = ns;
printf(" ++\n");
}
#endif
w = ww;
w += d;
x = xx;
break;
}
if (ps == s)
@ -3173,7 +3177,6 @@ System* Score::collectSystem(LayoutContext& lc)
if (!(key1 == key2)) {
// locate a key sig. in next measure and, if found,
// check if it has court. sig turned off
//?? Segment* s = toMeasure(lc.curMeasure)->findSegment(Segment::Type::KeySig, tick);
Segment* s = m->findSegment(Segment::Type::KeySig, tick);
if (s) {
KeySig* ks = toKeySig(s->element(staff->idx() * VOICES));
@ -3342,7 +3345,7 @@ bool Score::collectPage(LayoutContext& lc)
}
int stick = -1;
int etick ;
int etick = -1;
int tracks = nstaves() * VOICES;
for (System* s : page->systems()) {
for (MeasureBase* mb : s->measures()) {
@ -3405,15 +3408,17 @@ bool Score::collectPage(LayoutContext& lc)
for (Staff* staff : _staves)
staff->pitchOffsets().clear();
for (auto s : _spanner.map()) {
Spanner* sp = s.second;
if (sp->tick() >= etick || sp->tick2() < stick)
continue;
if (sp->isOttava() && sp->ticks() == 0) {
sp->setTick2(lastMeasure()->endTick());
sp->staff()->updateOttava();
if (etick != -1) {
for (auto s : _spanner.map()) {
Spanner* sp = s.second;
if (sp->tick() >= etick || sp->tick2() < stick)
continue;
if (sp->isOttava() && sp->ticks() == 0) {
sp->setTick2(lastMeasure()->endTick());
sp->staff()->updateOttava();
}
sp->layout();
}
sp->layout();
}
#if 0
@ -3440,7 +3445,7 @@ void Score::doLayout()
{
LayoutContext lc;
// printf("doLayout====\n");
qDebug("===doLayout");
if (_staves.empty() || first() == 0) {
// score is empty
@ -3459,9 +3464,9 @@ void Score::doLayout()
_scoreFont = ScoreFont::fontFactory(_style.value(StyleIdx::MusicalSymbolFont).toString());
_noteHeadWidth = _scoreFont->width(SymId::noteheadBlack, spatium() / SPATIUM20);
if (_cmdState.layoutFlags & LayoutFlag::FIX_PITCH_VELO)
if (cmdState().layoutFlags & LayoutFlag::FIX_PITCH_VELO)
updateVelo();
if (_cmdState.layoutFlags & LayoutFlag::PLAY_EVENTS)
if (cmdState().layoutFlags & LayoutFlag::PLAY_EVENTS)
createPlayEvents();
//---------------------------------------------------
@ -3504,15 +3509,15 @@ void Score::doLayout()
void Score::doLayoutRange(int stick, int etick)
{
qDebug("doLayoutRange==== %d-%d systems %d", stick, etick, _systems.size());
qDebug("===doLayoutRange %d-%d systems %d", stick, etick, _systems.size());
LayoutContext lc;
_scoreFont = ScoreFont::fontFactory(_style.value(StyleIdx::MusicalSymbolFont).toString());
_noteHeadWidth = _scoreFont->width(SymId::noteheadBlack, spatium() / SPATIUM20);
if (_cmdState.layoutFlags & LayoutFlag::FIX_PITCH_VELO)
if (cmdState().layoutFlags & LayoutFlag::FIX_PITCH_VELO)
updateVelo();
if (_cmdState.layoutFlags & LayoutFlag::PLAY_EVENTS)
if (cmdState().layoutFlags & LayoutFlag::PLAY_EVENTS)
createPlayEvents();
//---------------------------------------------------
@ -3520,6 +3525,9 @@ qDebug("doLayoutRange==== %d-%d systems %d", stick, etick, _systems.size());
//---------------------------------------------------
Measure* m = tick2measure(stick);
// start layout one measure earlier to handle clefs and cautionary elements
if (m->prevMeasure())
m = m->prevMeasure();
Page* p = m->system()->page();
System* s = p->systems().front();
@ -3548,9 +3556,14 @@ qDebug("doLayoutRange==== %d-%d systems %d", stick, etick, _systems.size());
while (collectPage(lc)) {
printf(" ...collectPage %d\n", lc.curPage);
if (!lc.pageChanged)
if (!lc.curSystem || (!lc.pageChanged && lc.curSystem->endTick() >= etick))
break;
}
if (!lc.curSystem) {
while (_pages.size() > lc.curPage) // Remove not needed pages. TODO: make undoable:
_pages.takeLast();
}
_systems.append(lc.systemList);
printf(" ==== systems %d\n", _systems.size());
@ -3558,5 +3571,4 @@ qDebug("doLayoutRange==== %d-%d systems %d", stick, etick, _systems.size());
v->layoutChanged();
}
}

View file

@ -464,7 +464,7 @@ void Lyrics::paste(MuseScoreView* scoreview)
layout();
score()->setLayoutAll();
score()->end();
score()->update();
txt = sl.join(" ");
QApplication::clipboard()->setText(txt, mode);

View file

@ -171,7 +171,7 @@ void MCursor::addPart(const QString& instrument)
void MCursor::saveScore()
{
QFile fp(_score->name() + ".mscx");
QFile fp(_score->fileInfo()->completeBaseName() + ".mscx");
if (!fp.open(QIODevice::WriteOnly)) {
qFatal("Open <%s> failed", qPrintable(fp.fileName()));
}

View file

@ -115,7 +115,6 @@ class MeasureBase : public Element {
Ms::Measure* nextMeasureMM() const;
Ms::Measure* prevMeasureMM() const;
virtual int ticks() const { return 0; }
virtual void write(Xml&) const override = 0;
virtual void write(Xml&, int, bool) const = 0;
@ -147,6 +146,7 @@ class MeasureBase : public Element {
virtual bool readProperties(XmlReader&) override;
virtual int tick() const override { return _tick; }
virtual int ticks() const { return 0; }
int endTick() const { return tick() + ticks(); }
void setTick(int t) { _tick = t; }

View file

@ -2096,12 +2096,12 @@ void Note::updateRelLine(int relLine, bool undoable)
chord()->undoChangeProperty(P_ID::STAFF_MOVE, 0);
}
Staff* s = score()->staff(staffIdx() + chord()->staffMove());
Staff* s = score()->staff(staffIdx() + chord()->staffMove());
ClefType clef = s->clef(chord()->tick());
int line = relStep(relLine, clef);
int line = relStep(relLine, clef);
if (line != _line) {
if (undoable)
if (undoable && _line != INVALID_LINE)
undoChangeProperty(P_ID::LINE, line);
else
setLine(line);

View file

@ -112,6 +112,8 @@ struct NoteVal {
NoteVal(int p) : pitch(p) {}
};
static const int INVALID_LINE = -10000;
//---------------------------------------------------------------------------------------
// @@ Note
/// Graphic representation of a note.
@ -215,7 +217,7 @@ class Note : public Element {
char _onTimeType { 0 }; // compatibility only 1 - user, 2 - offset
int _subchannel { 0 }; ///< articulation
int _line { 0 }; ///< y-Position; 0 - top line.
int _line { INVALID_LINE }; ///< y-Position; 0 - top line.
int _fret { -1 }; ///< for tablature view
int _string { -1 };
mutable int _tpc[2] { Tpc::TPC_INVALID, Tpc::TPC_INVALID }; ///< tonal pitch class (concert/transposing)

View file

@ -549,7 +549,7 @@ QString Page::replaceTextMacros(const QString& s) const
d += QString("%1").arg(score()->npages() + score()->pageNumberOffset());
break;
case 'f':
d += masterScore()->name().toHtmlEscaped();
d += masterScore()->fileInfo()->completeBaseName().toHtmlEscaped();
break;
case 'F':
d += masterScore()->fileInfo()->absoluteFilePath().toHtmlEscaped();
@ -889,5 +889,13 @@ QRectF Page::tbbox()
return abbox();
}
//---------------------------------------------------------
// endTick
//---------------------------------------------------------
int Page::endTick() const
{
return _systems.empty() ? -1 : _systems.back()->measures().back()->endTick();
}
}

View file

@ -173,6 +173,7 @@ class Page : public Element {
Segment**, QPointF* offset) const;
QList<const Element*> elements(); ///< list of visible elements
QRectF tbbox(); // tight bounding box, excluding white space
int endTick() const;
};
extern const PaperSize paperSizes[];

View file

@ -74,6 +74,8 @@ class Part : public QObject, public ScoreElement {
Part(Score* = 0);
void initFromInstrTemplate(const InstrumentTemplate*);
virtual const char* name() const override { return "Part"; }
void read(XmlReader&);
void write(Xml& xml) const;

View file

@ -598,7 +598,7 @@ void Score::setShowInvisible(bool v)
_showInvisible = v;
rebuildBspTree();
setUpdateAll();
end();
update();
}
//---------------------------------------------------------
@ -609,7 +609,7 @@ void Score::setShowUnprintable(bool v)
{
_showUnprintable = v;
setUpdateAll();
end();
update();
}
//---------------------------------------------------------
@ -620,7 +620,7 @@ void Score::setShowFrames(bool v)
{
_showFrames = v;
setUpdateAll();
end();
update();
}
//---------------------------------------------------------
@ -631,7 +631,7 @@ void Score::setShowPageborders(bool v)
{
_showPageborders = v;
setUpdateAll();
end();
update();
}
//---------------------------------------------------------
@ -1201,14 +1201,14 @@ void Score::addElement(Element* element)
if (ss->system())
ss->system()->add(ss);
}
_cmdState.layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
cmdState().layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
o->staff()->updateOttava();
_playlistDirty = true;
}
break;
case Element::Type::DYNAMIC:
_cmdState.layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
cmdState().layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
_playlistDirty = true;
break;
@ -1232,7 +1232,7 @@ void Score::addElement(Element* element)
ic->part()->setInstrument(ic->instrument(), tickStart);
transpositionChanged(ic->part(), oldV, tickStart, tickEnd);
masterScore()->rebuildMidiMapping();
_cmdState._instrumentsChanged = true;
cmdState()._instrumentsChanged = true;
}
break;
@ -1335,13 +1335,13 @@ void Score::removeElement(Element* element)
ss->system()->remove(ss);
}
o->staff()->updateOttava();
_cmdState.layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
cmdState().layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
_playlistDirty = true;
}
break;
case Element::Type::DYNAMIC:
_cmdState.layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
cmdState().layoutFlags |= LayoutFlag::FIX_PITCH_VELO;
_playlistDirty = true;
break;
@ -1377,7 +1377,7 @@ void Score::removeElement(Element* element)
ic->part()->removeInstrument(tickStart);
transpositionChanged(ic->part(), oldV, tickStart, tickEnd);
masterScore()->rebuildMidiMapping();
_cmdState._instrumentsChanged = true;
cmdState()._instrumentsChanged = true;
}
break;
@ -1664,7 +1664,7 @@ void MasterScore::addExcerpt(Score* score)
Excerpt* ex = new Excerpt(this);
ex->setPartScore(score);
excerpts().append(ex);
ex->setTitle(score->name());
ex->setTitle(score->fileInfo()->completeBaseName());
for (Staff* s : score->staves()) {
LinkedStaves* ls = s->linkedStaves();
if (ls == 0)
@ -1735,16 +1735,6 @@ void Score::setSynthesizerState(const SynthesizerState& s)
_synthesizerState = s;
}
//---------------------------------------------------------
// setLayoutAll
//---------------------------------------------------------
void Score::setLayoutAll()
{
for (Score* score : scoreList())
score->_cmdState.setUpdateMode(UpdateMode::LayoutAll);
}
//---------------------------------------------------------
// removeAudio
//---------------------------------------------------------
@ -1923,7 +1913,7 @@ void Score::splitStaff(int staffIdx, int splitPoint)
undoChangeKeySig(ns, 0, s->keySigEvent(0));
masterScore()->rebuildMidiMapping();
_cmdState._instrumentsChanged = true;
cmdState()._instrumentsChanged = true;
doLayout();
//
@ -2459,7 +2449,7 @@ void Score::padToggle(Pad n)
void Score::deselect(Element* el)
{
_cmdState.refresh |= el->abbox();
addRefresh(el->abbox());
_selection.remove(el);
setSelectionChanged(true);
}
@ -2508,7 +2498,7 @@ void Score::selectSingle(Element* e, int staffIdx)
select(e, SelectType::RANGE, staffIdx);
return;
}
_cmdState.refresh |= e->abbox();
addRefresh(e->abbox());
_selection.add(e);
_is.setTrack(e->track());
selState = SelState::LIST;
@ -2557,7 +2547,7 @@ void Score::selectAdd(Element* e)
_selection.updateSelectedElements();
}
else { // None or List
_cmdState.refresh |= e->abbox();
addRefresh(e->abbox());
if (_selection.elements().contains(e))
_selection.remove(e);
else {
@ -4107,5 +4097,14 @@ void MasterScore::removeOmr()
_omr = 0;
}
//---------------------------------------------------------
// addRefresh
//---------------------------------------------------------
void Score::addRefresh(const QRectF& r)
{
_updateState.refresh |= r;
cmdState().setUpdateMode(UpdateMode::Update);
}
}

View file

@ -243,7 +243,7 @@ enum class UpdateMode {
DoNothing,
Update, // do screen refresh of QRectF "refresh"
UpdateAll, // do complete screen refresh
LayoutTick, // do partial layout for tick range
LayoutRange, // do partial layout for tick range
LayoutAll, // do complete layout
};
@ -261,29 +261,35 @@ class CmdState {
int _endTick; // end tick for mode LayoutTick
public:
QRectF refresh; ///< area to update, canvas coordinates
LayoutFlags layoutFlags;
bool _playNote; ///< play selected note after command
bool _playChord; ///< play whole chord for the selected note
bool _excerptsChanged;
bool _instrumentsChanged;
bool _selectionChanged;
void reset();
UpdateMode updateMode() const { return _updateMode; }
void setUpdateMode(UpdateMode m);
bool layoutAll() const { return _updateMode == UpdateMode::LayoutAll; }
bool updateAll() const { return int(_updateMode) >= int(UpdateMode::UpdateAll); }
bool layoutAll() const { return _updateMode == UpdateMode::LayoutAll; }
bool layoutRange() const { return _updateMode == UpdateMode::LayoutRange; }
bool updateAll() const { return int(_updateMode) >= int(UpdateMode::UpdateAll); }
bool updateRange() const { return _updateMode == UpdateMode::Update; }
void setTick(int t);
int startTick() const { return _startTick; }
int endTick() const { return _endTick; }
};
class UpdateState {
public:
QRectF refresh; ///< area to update, canvas coordinates
bool _playNote { false }; ///< play selected note after command
bool _playChord { false }; ///< play whole chord for the selected note
bool _selectionChanged { false };
};
class MasterScore;
//---------------------------------------------------------
//---------------------------------------------------------------------------------------
// @@ Score
// @P composer string composer of the score (read only)
// @P duration int duration of score in seconds (read only)
@ -309,13 +315,15 @@ class MasterScore;
// @P poet string poet of the score (read only)
// @P subtitle string subtitle of the score (read only)
// @P title string title of the score (read only)
//---------------------------------------------------------
//
// a Score has always an associated MasterScore
//---------------------------------------------------------------------------------------
class Score : public QObject, public ScoreElement {
Q_OBJECT
Q_PROPERTY(QString composer READ composer)
Q_PROPERTY(int duration READ duration)
//TODO Q_PROPERTY(QQmlListProperty<Ms::Excerpt> excerpts READ qmlExcerpts)
//TODO-ws Q_PROPERTY(QQmlListProperty<Ms::Excerpt> excerpts READ qmlExcerpts)
Q_PROPERTY(Ms::Measure* firstMeasure READ firstMeasure)
Q_PROPERTY(Ms::Measure* firstMeasureMM READ firstMeasureMM)
Q_PROPERTY(int harmonyCount READ harmonyCount)
@ -326,7 +334,7 @@ class Score : public QObject, public ScoreElement {
Q_PROPERTY(Ms::Measure* lastMeasureMM READ lastMeasureMM)
Q_PROPERTY(Ms::Segment* lastSegment READ lastSegment)
Q_PROPERTY(int lyricCount READ lyricCount)
Q_PROPERTY(QString name READ name WRITE setName)
//TODO-ws Q_PROPERTY(QString name READ name WRITE setName)
Q_PROPERTY(int nmeasures READ nmeasures)
Q_PROPERTY(int npages READ npages)
Q_PROPERTY(int nstaves READ nstaves)
@ -373,22 +381,21 @@ class Score : public QObject, public ScoreElement {
SpannerMap _spanner;
std::set<Spanner*> _unmanagedSpanner;
UpdateState _updateState;
//
// generated objects during layout:
//
QList<Page*> _pages; // pages are build from systems
QList<System*> _systems; // measures are akkumulated to systems
InputState _is;
MStyle _style;
bool _created { false }; ///< file is never saved, has generated name
QString _tmpName; ///< auto saved with this name if not empty
QString _importedFilePath; // file from which the score was imported, or empty
bool _created { false }; ///< file is never saved, has generated name
QString _tmpName; ///< auto saved with this name if not empty
QString _importedFilePath; // file from which the score was imported, or empty
CmdState _cmdState; // modified during cmd processing
bool _showInvisible { true };
bool _showUnprintable { true };
@ -405,12 +412,11 @@ class Score : public QObject, public ScoreElement {
bool _defaultsRead { false }; ///< defaults were read at MusicXML import, allow export of defaults in convertermode
Qt::KeyboardModifiers keyState { 0 };
QList<Part*> _parts;
QList<Staff*> _staves;
int _pos[3]; ///< 0 - current, 1 - left loop, 2 - right loop
int _pos[3]; ///< 0 - current, 1 - left loop, 2 - right loop
bool _foundPlayPosAfterRepeats; ///< Temporary used during playback rendering
///< indicating if playPos after expanded repeats
@ -482,7 +488,6 @@ class Score : public QObject, public ScoreElement {
void addAudioTrack();
QList<Fraction> splitGapToMeasureBoundaries(ChordRest*, Fraction);
void pasteChordRest(ChordRest* cr, int tick, const Interval&);
// void init();
qreal cautionaryWidth(Measure* m, bool& hasCourtesy);
void selectSingle(Element* e, int staffIdx);
@ -491,7 +496,6 @@ class Score : public QObject, public ScoreElement {
QQmlListProperty<Ms::Part> qmlParts() { return QQmlListProperty<Ms::Part>(this, _parts); }
void getNextMeasure(LayoutContext&); // get next measure for layout
bool collectPage(LayoutContext&);
System* collectSystem(LayoutContext&);
@ -520,6 +524,7 @@ class Score : public QObject, public ScoreElement {
virtual inline QList<Excerpt*>& excerpts();
virtual inline const QList<Excerpt*>& excerpts() const;
virtual const char* name() const override { return "Score"; }
void rebuildBspTree();
bool noStaves() const { return _staves.empty(); }
@ -646,24 +651,31 @@ class Score : public QObject, public ScoreElement {
void repitchNote(const Position& pos, bool replace);
void cmdAddPitch(int pitch, bool addFlag);
//@ to be used at least once by plugins of type "dialog" before score modifications to make them undoable
Q_INVOKABLE void startCmd(); // start undoable command
//@ to be used at least once by plugins of type "dialog" after score modifications to make them undoable
Q_INVOKABLE void endCmd(bool rollback = false); // end undoable command
void end(); // layout & update canvas
void end1();
void startCmd(); // start undoable command
void endCmd(bool rollback = false); // end undoable command
void update();
void end() { update(); }
void cmdRemoveTimeSig(TimeSig*);
void cmdAddTimeSig(Measure*, int staffIdx, TimeSig*, bool local);
void setUpdateAll() { _cmdState.setUpdateMode(UpdateMode::UpdateAll); }
void setLayoutAll();
void setLayout(int t) { _cmdState.setTick(t); }
UpdateMode updateMode() const { return _cmdState.updateMode(); }
virtual inline void setUpdateAll();
virtual inline void setLayoutAll();
virtual inline void setLayout(int);
virtual inline CmdState& cmdState();
virtual inline void addLayoutFlags(LayoutFlags);
virtual inline void setExcerptsChanged(bool);
virtual inline void setInstrumentsChanged(bool);
void addRefresh(const QRectF& r) { _cmdState.refresh |= r; }
const QRectF& getRefresh() const { return _cmdState.refresh; }
bool playNote() const { return _updateState._playNote; }
void setPlayNote(bool v) { _updateState._playNote = v; }
bool playChord() const { return _updateState._playChord; }
void setPlayChord(bool v) { _updateState._playChord = v; }
bool selectionChanged() const { return _updateState._selectionChanged; }
void setSelectionChanged(bool val) { _updateState._selectionChanged = val; }
void addRefresh(const QRectF&);
// const QRectF& getRefresh() const { return _updateState.refresh; }
void changeVoice(int);
@ -916,7 +928,6 @@ class Score : public QObject, public ScoreElement {
SynthesizerState& synthesizerState() { return _synthesizerState; }
void setSynthesizerState(const SynthesizerState& s);
void addLayoutFlags(LayoutFlags val) { _cmdState.layoutFlags |= val; }
void updateHairpin(Hairpin*); // add/modify hairpin to pitchOffset list
void removeHairpin(Hairpin*); // remove hairpin from pitchOffset list
Volta* searchVolta(int tick) const;
@ -959,16 +970,6 @@ class Score : public QObject, public ScoreElement {
void addViewer(MuseScoreView* v) { viewer.append(v); }
void removeViewer(MuseScoreView* v) { viewer.removeAll(v); }
const QList<MuseScoreView*>& getViewer() const { return viewer; }
bool playNote() const { return _cmdState._playNote; }
void setPlayNote(bool v) { _cmdState._playNote = v; }
bool playChord() const { return _cmdState._playChord; }
void setPlayChord(bool v) { _cmdState._playChord = v; }
bool excerptsChanged() const { return _cmdState._excerptsChanged; }
void setExcerptsChanged(bool val) { _cmdState._excerptsChanged = val; }
bool instrumentsChanged() const { return _cmdState._instrumentsChanged; }
void setInstrumentsChanged(bool val) { _cmdState._instrumentsChanged = val; }
bool selectionChanged() const { return _cmdState._selectionChanged; }
void setSelectionChanged(bool val) { _cmdState._selectionChanged = val; }
LayoutMode layoutMode() const { return _layoutMode; }
void setLayoutMode(LayoutMode lm) { _layoutMode = lm; }
@ -1082,7 +1083,7 @@ class Score : public QObject, public ScoreElement {
QFileInfo* fileInfo() { return &info; }
const QFileInfo* fileInfo() const { return &info; }
QString name() const { return info.completeBaseName(); }
// QString name() const { return info.completeBaseName(); }
void setName(const QString& s);
virtual QVariant getProperty(P_ID) const override;
@ -1110,6 +1111,8 @@ class MasterScore : public Score {
Revisions* _revisions;
QMap<int, LinkedElements*> _elinks;
CmdState _cmdState; // modified during cmd processing
Omr* _omr;
bool _showOmr;
@ -1147,7 +1150,20 @@ class MasterScore : public Score {
virtual QMap<int, LinkedElements*>& links() override { return _elinks; }
virtual QQueue<MidiInputEvent> midiInputQueue() override { return _midiInputQueue; }
Revisions* revisions() { return _revisions; }
virtual void setUpdateAll() override { _cmdState.setUpdateMode(UpdateMode::UpdateAll); }
virtual void setLayoutAll() override { _cmdState.setUpdateMode(UpdateMode::LayoutAll); }
virtual void setLayout(int t) override { _cmdState.setTick(t); }
virtual CmdState& cmdState() override { return _cmdState; }
virtual void addLayoutFlags(LayoutFlags val) override { _cmdState.layoutFlags |= val; }
virtual void setExcerptsChanged(bool val) override { _cmdState._excerptsChanged = val; }
virtual void setInstrumentsChanged(bool val) override { _cmdState._instrumentsChanged = val; }
bool excerptsChanged() const { return _cmdState._excerptsChanged; }
bool instrumentsChanged() const { return _cmdState._instrumentsChanged; }
// UpdateMode updateMode() const { return _cmdState.updateMode(); }
Revisions* revisions() { return _revisions; }
bool isSavable() const;
void setTempomap(TempoMap* tm);
@ -1193,6 +1209,13 @@ inline TimeSigMap* Score::sigmap() const { return _masterScore->sig
inline QList<Excerpt*>& Score::excerpts() { return _masterScore->excerpts(); }
inline const QList<Excerpt*>& Score::excerpts() const { return _masterScore->excerpts(); }
inline QQueue<MidiInputEvent> Score::midiInputQueue() { return _masterScore->midiInputQueue(); }
inline void Score::setUpdateAll() { _masterScore->setUpdateAll(); }
inline void Score::setLayoutAll() { _masterScore->setLayoutAll(); }
inline void Score::setLayout(int tick) { _masterScore->setLayout(tick); }
inline CmdState& Score::cmdState() { return _masterScore->cmdState(); }
inline void Score::addLayoutFlags(LayoutFlags f) { _masterScore->addLayoutFlags(f); }
inline void Score::setExcerptsChanged(bool val) { setExcerptsChanged(val); }
inline void Score::setInstrumentsChanged(bool v) { setInstrumentsChanged(v); }
extern MasterScore* gscore;
extern void fixTicks();

View file

@ -108,8 +108,8 @@ void ScoreElement::unlink()
void ScoreElement::undoUnlink()
{
if (_links)
_score->undo(new Unlink(this));
// if (_links)
//TODO-ws _score->undo(new Unlink(this));
}
//---------------------------------------------------------

View file

@ -55,6 +55,7 @@ class ScoreElement {
virtual QVariant getProperty(P_ID) const = 0;
virtual bool setProperty(P_ID, const QVariant&) = 0;
virtual const char* name() const = 0;
virtual QVariant propertyDefault(P_ID) const { return QVariant(); }
virtual void resetProperty(P_ID id);

View file

@ -240,7 +240,7 @@ void Score::write(Xml& xml, bool selectionOnly)
}
}
else
xml.tag("name", masterScore()->name());
xml.tag("name", masterScore()->fileInfo()->completeBaseName());
xml.etag();
if (unhide) {

View file

@ -636,10 +636,8 @@ void Segment::remove(Element* el)
break;
case Element::Type::CLEF:
if (!el->generated()) {
el->staff()->removeClef(static_cast<Clef*>(el));
updateNoteLines(this, el->track());
}
el->staff()->removeClef(static_cast<Clef*>(el));
// updateNoteLines(this, el->track());
// fall through
case Element::Type::BAR_LINE:
@ -1374,8 +1372,8 @@ qreal Segment::minHorizontalDistance(Segment* ns) const
qreal w = 0.0;
for (unsigned staffIdx = 0; staffIdx < _shapes.size(); ++staffIdx) {
qreal d = shape(staffIdx).minHorizontalDistance(ns->shape(staffIdx));
if (st == Segment::Type::ChordRest && nst == Segment::Type::Clef)
d = qMax(d, minRight()) + score()->styleP(StyleIdx::noteBarDistance);
// if (st == Segment::Type::ChordRest && nst == Segment::Type::Clef)
// d = qMax(d, minRight()) + score()->styleP(StyleIdx::noteBarDistance);
w = qMax(w, d);
}
@ -1415,6 +1413,7 @@ qreal Segment::minHorizontalDistance(Segment* ns) const
w = 0.0;
if (ns)
w += ns->extraLeadingSpace().val() * spatium();
// qDebug("minHDist %f %s %s", w, subTypeName(), ns ? ns->subTypeName() : "-0-");
return w;
}

View file

@ -15,7 +15,7 @@
namespace Ms {
// #define DEBUG_SHAPES
#define DEBUG_SHAPES
class Segment;

View file

@ -290,6 +290,7 @@ void Staff::dumpTimeSigs(const char* title) const
void Staff::setClef(Clef* clef)
{
// qDebug("Staff::setClef generated %d", clef->generated());
if (clef->generated())
return;
int tick = clef->segment()->tick();
@ -309,6 +310,7 @@ void Staff::setClef(Clef* clef)
void Staff::removeClef(Clef* clef)
{
// qDebug("Staff::removeClef generated %d", clef->generated());
if (clef->generated())
return;
int tick = clef->segment()->tick();

View file

@ -139,6 +139,8 @@ private:
void initFromStaffType(const StaffType* staffType);
void init(const Staff*);
virtual const char* name() const override { return "Staff"; }
bool isTop() const;
QString partName() const;
int rstaff() const;

View file

@ -1171,5 +1171,14 @@ bool System::pageBreak() const
{
return ml.back()->pageBreak();
}
//---------------------------------------------------------
// endTick
//---------------------------------------------------------
int System::endTick() const
{
return measures().back()->endTick();
}
}

View file

@ -128,6 +128,7 @@ class System : public Element {
MeasureBase* measure(int idx) { return ml[idx]; }
Measure* firstMeasure() const;
Measure* lastMeasure() const;
int endTick() const;
MeasureBase* prevMeasure(const MeasureBase*) const;
MeasureBase* nextMeasure(const MeasureBase*) const;

View file

@ -618,11 +618,6 @@ void Tuplet::write(Xml& xml) const
if (tuplet())
xml.tag("Tuplet", tuplet()->id());
Element::writeProperties(xml);
printf("Tuplet::write %d %d\n",
int(getProperty(P_ID::DIRECTION).value<Direction>()),
int(propertyDefault(P_ID::DIRECTION).value<Direction>())
);
writeProperty(xml, P_ID::DIRECTION);
writeProperty(xml, P_ID::NUMBER_TYPE);
writeProperty(xml, P_ID::BRACKET_TYPE);

View file

@ -75,6 +75,12 @@
#include "utils.h"
#include "glissando.h"
#ifdef QT_NO_DEBUG
Q_LOGGING_CATEGORY(undoRedo, "undoRedo", QtCriticalMsg)
#else
Q_LOGGING_CATEGORY(undoRedo, "undoRedo")
#endif
namespace Ms {
extern Measure* tick2measure(int tick);
@ -139,8 +145,8 @@ void UndoCommand::undo()
{
int n = childList.size();
for (int i = n-1; i >= 0; --i) {
#ifdef DEBUG_UNDO
qDebug(" undo<%s> %p", childList[i]->name(), childList[i]);
#ifndef QT_NO_DEBUG
qCDebug(undoRedo) << " undo<" << childList[i]->name() << ">";
#endif
childList[i]->undo();
}
@ -155,8 +161,8 @@ void UndoCommand::redo()
{
int n = childList.size();
for (int i = 0; i < n; ++i) {
#ifdef DEBUG_UNDO
qDebug(" redo<%s> %p", childList[i]->name(), childList[i]);
#ifndef QT_NO_DEBUG
qCDebug(undoRedo) << " redo<" << childList[i]->name() << ">";
#endif
childList[i]->redo();
}
@ -206,7 +212,7 @@ UndoStack::~UndoStack()
void UndoStack::beginMacro()
{
if (curCmd) {
qDebug("UndoStack:beginMacro(): already active");
qWarning("UndoStack:beginMacro(): already active");
return;
}
curCmd = new UndoCommand();
@ -219,7 +225,7 @@ void UndoStack::beginMacro()
void UndoStack::endMacro(bool rollback)
{
if (curCmd == 0) {
qDebug("UndoStack:endMacro(): not active");
qWarning("UndoStack:endMacro(): not active");
return;
}
if (rollback)
@ -245,19 +251,19 @@ void UndoStack::push(UndoCommand* cmd)
{
if (!curCmd) {
// this can happen for layout() outside of a command (load)
// qDebug("UndoStack:push(): no active command, UndoStack %p", this);
// qWarning("UndoStack:push(): no active command, UndoStack %p", this);
cmd->redo();
delete cmd;
return;
}
#ifdef DEBUG_UNDO
#ifndef QT_NO_DEBUG
if (!strcmp(cmd->name(), "ChangeProperty")) {
ChangeProperty* cp = static_cast<ChangeProperty*>(cmd);
qDebug("UndoStack::push <%s> %p id %d", cmd->name(), cmd, int(cp->getId()));
qCDebug(undoRedo, "UndoStack::push <%s> id %s", cmd->name(), propertyName(cp->getId()));
}
else {
qDebug("UndoStack::push <%s> %p", cmd->name(), cmd);
qCDebug(undoRedo, "UndoStack::push <%s>", cmd->name());
}
#endif
curCmd->appendChild(cmd);
@ -273,7 +279,7 @@ void UndoStack::push1(UndoCommand* cmd)
if (curCmd)
curCmd->appendChild(cmd);
else
qDebug("UndoStack:push1(): no active command, UndoStack %p", this);
qWarning("UndoStack:push1(): no active command, UndoStack %p", this);
}
//---------------------------------------------------------
@ -283,7 +289,7 @@ void UndoStack::push1(UndoCommand* cmd)
void UndoStack::pop()
{
if (!curCmd) {
qDebug("UndoStack:pop(): no active command");
qWarning("UndoStack:pop(): no active command");
return;
}
UndoCommand* cmd = curCmd->removeChild();
@ -463,7 +469,7 @@ void Score::undoChangeKeySig(Staff* ostaff, int tick, KeySigEvent key)
Score* score = staff->score();
Measure* measure = score->tick2measure(tick);
if (!measure) {
qDebug("measure for tick %d not found!", tick);
qWarning("measure for tick %d not found!", tick);
continue;
}
Segment* s = measure->undoGetSegment(Segment::Type::KeySig, tick);
@ -516,7 +522,7 @@ void Score::undoChangeClef(Staff* ostaff, Segment* seg, ClefType st)
int tick = seg->tick();
Measure* measure = score->tick2measure(tick);
if (!measure) {
qDebug("measure for tick %d not found!", tick);
qWarning("measure for tick %d not found!", tick);
continue;
}
@ -1058,7 +1064,7 @@ void Score::undoAddElement(Element* element)
}
Segment* seg = m->findSegment(st, tick);
if (seg == 0) {
qDebug("undoAddSegment: segment not found");
qWarning("undoAddSegment: segment not found");
break;
}
Articulation* na = static_cast<Articulation*>(ne);
@ -1087,7 +1093,7 @@ void Score::undoAddElement(Element* element)
Measure* m = score->tick2measure(tick);
Segment* seg = m->findSegment(Segment::Type::ChordRest, tick);
if (seg == 0) {
qDebug("undoAddSegment: segment not found");
qWarning("undoAddSegment: segment not found");
break;
}
int ntrack = staffIdx * VOICES + element->voice();
@ -1268,7 +1274,7 @@ void Score::undoAddElement(Element* element)
undo(new AddElement(nbreath));
}
else
qDebug("undoAddElement: unhandled: <%s>", element->name());
qWarning("undoAddElement: unhandled: <%s>", element->name());
}
}
@ -1370,7 +1376,7 @@ void Score::undoAddCR(ChordRest* cr, Measure* measure, int tick)
}
}
if (nt == 0)
qDebug("linked tuplet not found");
qWarning("linked tuplet not found");
}
newcr->setTuplet(nt);
}
@ -1530,7 +1536,7 @@ void AddElement::redo()
// name
//---------------------------------------------------------
#ifdef DEBUG_UNDO
#ifndef QT_NO_DEBUG
const char* AddElement::name() const
{
static char buffer[64];
@ -1552,35 +1558,6 @@ RemoveElement::RemoveElement(Element* e)
Score* score = element->score();
if (element->isChordRest1()) {
#if 0
// do not delete pending slur in note entry mode
Slur* pendingSlur = 0;
for (Score* sc : score->scoreList()) {
if (sc->noteEntryMode()) {
pendingSlur = sc->inputState().slur();
break;
}
}
// remove any slurs pointing to this chor/rest
QList<Spanner*> sl;
int tick = static_cast<ChordRest*>(element)->tick();
for (auto i : score->spanner()) { // TODO: dont search whole list
Spanner* s = i.second;
if (pendingSlur && pendingSlur->linkList().contains(s)) {
if (s->startElement() == e)
s->setStartElement(nullptr);
else if (s->endElement() == e)
s->setEndElement(nullptr);
continue;
}
if (s->type() == Element::Type::SLUR && (s->startElement() == e || s->endElement() == e))
sl.append(s);
else if ((s->tick() == tick) && (s->track() == element->track()))
sl.append(s);
}
for (auto s : sl) // actually remove scheduled spanners
score->undo(new RemoveElement(s));
#endif
ChordRest* cr = static_cast<ChordRest*>(element);
if (cr->tuplet() && cr->tuplet()->elements().size() <= 1)
score->undo(new RemoveElement(cr->tuplet()));
@ -1667,14 +1644,14 @@ void RemoveElement::redo()
// name
//---------------------------------------------------------
#ifdef DEBUG_UNDO
#ifndef QT_NO_DEBUG
const char* RemoveElement::name() const
{
static char buffer[64];
if (element->isText())
snprintf(buffer, 64, "Rem: %s <%s>", element->name(), qPrintable(static_cast<Text*>(element)->plainText()));
snprintf(buffer, 64, "Remove: %s <%s>", element->name(), qPrintable(static_cast<Text*>(element)->plainText()));
else
snprintf(buffer, 64, "Rem: %s", element->name());
snprintf(buffer, 64, "Remove: %s", element->name());
return buffer;
}
#endif
@ -2338,7 +2315,7 @@ void ChangePatch::flip()
patch = op;
if (MScore::seq == 0) {
qDebug("ChangePatch: no seq");
qWarning("ChangePatch: no seq");
return;
}
@ -3229,16 +3206,9 @@ void ChangeStaffUserDist::flip()
void ChangeProperty::flip()
{
#ifdef DEBUG_UNDO
qDebug()
<< "ChangeProperty::flip(): "
<< propertyName(id)
<< " "
<< element->getProperty(id)
<< " -> "
<< property
;
#endif
// #ifndef QT_NO_DEBUG
qCDebug(undoRedo) << "ChangeProperty::flip():" << element->name() << propertyName(id) << element->getProperty(id) << "->" << property;
// #endif
if (id == P_ID::SPANNER_TICK || id == P_ID::SPANNER_TICKS)
static_cast<Element*>(element)->score()->removeSpanner(static_cast<Spanner*>(element));
@ -3405,11 +3375,11 @@ void ChangeSpannerElements::flip()
}
// if current spanner, just use stored start and end elements
else {
newStartNote = static_cast<Note*>(startElement);
newEndNote = static_cast<Note*>(endElement);
newStartNote = static_cast<Note*>(startElement);
newEndNote = static_cast<Note*>(endElement);
}
// update spanner's start and end notes
if (newStartNote != nullptr && newEndNote != nullptr) {
if (newStartNote && newEndNote) {
oldStartNote->removeSpannerFor(sp);
oldEndNote->removeSpannerBack(sp);
sp->setNoteSpan(newStartNote, newEndNote);
@ -3494,18 +3464,16 @@ void ChangeNoteEvent::flip()
}
//---------------------------------------------------------
// Link
// LinkUnlink
//---------------------------------------------------------
void Link::redo()
void LinkUnlink::doLink()
{
if (MScore::debugMode)
qDebug("Link:redo() link %p (e) to %p (le)", e, le);
Q_ASSERT(le != nullptr);
Q_ASSERT(le);
e->linkTo(le);
}
void Link::undo()
void LinkUnlink::doUnlink()
{
// find appropriate target element to unlink
// use current le if valid; pick something else in link list if not but that shouldn't happen!
@ -3514,7 +3482,7 @@ void Link::undo()
// don't use current le if null or if it is no longer linked (shouldn't happen)
if (le && !l->contains(le)) {
le = nullptr;
qDebug("Link::undo(): current le %p no longer linked", le);
qWarning("doUnlink(): current le %p no longer linked", le);
}
if (!le) {
// shouldn't happen
@ -3529,50 +3497,12 @@ void Link::undo()
}
}
else
qDebug("Link::undo(): current element %p has no links", e);
if (MScore::debugMode)
qDebug("Link::undo(): unlink %p (le) from %p (e)", le, e);
qWarning("doUnlink(): current element %p has no links", e);
if (le)
le->unlink();
else
qDebug("Link::undo(): nothing found to unlink");
}
//---------------------------------------------------------
// Unlink
//---------------------------------------------------------
void Unlink::redo()
{
// Q_ASSERT(le == nullptr);
// find appropriate target element to unlink
// use current le if valid; pick something else in link list if not
// do unlink e if we wanted to unlink it in the first place (redo)
const LinkedElements* l = e->links();
if (l != nullptr) {
// find something other than current element (e) in link list, so we can link again on undo
for (ScoreElement* ee : *l) {
if (e != ee) {
le = ee;
break;
}
}
if (e)
e->unlink();
}
else
qDebug("doUnlink(): current element %p has no links", e);
}
void Unlink::undo()
{
if (MScore::debugMode)
qDebug("LinkUnlink: link %p (e) to %p (le)", e, le);
Q_ASSERT(le != nullptr);
e->linkTo(le);
qWarning("doUnlink(): nothing found to unlink");
}
void LinkStaff::redo() { s1->linkTo(s2); }

View file

@ -40,6 +40,8 @@
#include "note.h"
#include "drumset.h"
Q_DECLARE_LOGGING_CATEGORY(undoRedo)
namespace Ms {
class ElementList;
@ -83,8 +85,8 @@ enum class PlayEventType : char;
// #define DEBUG_UNDO
#ifdef DEBUG_UNDO
#define UNDO_NAME(a) virtual const char* name() const { return a; }
#ifndef QT_NO_DEBUG
#define UNDO_NAME(a) virtual const char* name() const override { return a; }
#else
#define UNDO_NAME(a)
#endif
@ -110,8 +112,8 @@ class UndoCommand {
int childCount() const { return childList.size(); }
void unwind();
virtual void cleanup(bool undo);
#ifdef DEBUG_UNDO
virtual const char* name() const { return "UndoCommand"; }
#ifndef QT_NO_DEBUG
virtual const char* name() const { return "UndoCommand"; }
#endif
};
@ -559,8 +561,8 @@ class AddElement : public UndoCommand {
virtual void undo();
virtual void redo();
virtual void cleanup(bool);
#ifdef DEBUG_UNDO
virtual const char* name() const;
#ifndef QT_NO_DEBUG
virtual const char* name() const override;
#endif
};
@ -576,8 +578,8 @@ class RemoveElement : public UndoCommand {
virtual void undo();
virtual void redo();
virtual void cleanup(bool);
#ifdef DEBUG_UNDO
virtual const char* name() const;
#ifndef QT_NO_DEBUG
virtual const char* name() const override;
#endif
};
@ -1252,6 +1254,22 @@ class ChangeNoteEvent : public UndoCommand {
UNDO_NAME("ChangeNoteEvent")
};
//---------------------------------------------------------
// LinkUnlink
//---------------------------------------------------------
class LinkUnlink : public UndoCommand {
ScoreElement* e;
ScoreElement* le;
protected:
void doLink();
void doUnlink();
public:
LinkUnlink(ScoreElement* _e, ScoreElement* _le) : e(_e), le(_le) {}
};
#if 0
//---------------------------------------------------------
// Unlink
//---------------------------------------------------------
@ -1265,7 +1283,7 @@ class Unlink : public UndoCommand {
virtual void redo() override;
UNDO_NAME("Unlink")
};
#endif
//---------------------------------------------------------
// Link
//---------------------------------------------------------

View file

@ -192,7 +192,7 @@ void DrumrollEditor::setStaff(Staff* st)
{
staff = st;
_score = staff->score();
setWindowTitle(tr("MuseScore: <%1> Staff: %2").arg(_score->name()).arg(st->idx()));
setWindowTitle(tr("MuseScore: <%1> Staff: %2").arg(_score->fileInfo()->completeBaseName()).arg(st->idx()));
TempoMap* tl = _score->tempomap();
TimeSigMap* sl = _score->sigmap();
for (int i = 0; i < 3; ++i)

View file

@ -224,7 +224,7 @@ bool MuseScore::checkDirty(Score* s)
if (s->dirty() || s->created()) {
QMessageBox::StandardButton n = QMessageBox::warning(this, tr("MuseScore"),
tr("Save changes to the score \"%1\"\n"
"before closing?").arg(s->name()),
"before closing?").arg(s->fileInfo()->completeBaseName()),
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,
QMessageBox::Save);
if (n == QMessageBox::Save) {
@ -413,11 +413,11 @@ bool MuseScore::saveFile(Score* score)
return false;
}
score->setCreated(false);
setWindowTitle("MuseScore: " + score->name());
setWindowTitle("MuseScore: " + score->fileInfo()->completeBaseName());
int idx = scoreList.indexOf(score->masterScore());
tab1->setTabText(idx, score->name());
tab1->setTabText(idx, score->fileInfo()->completeBaseName());
if (tab2)
tab2->setTabText(idx, score->name());
tab2->setTabText(idx, score->fileInfo()->completeBaseName());
QString tmp = score->tmpName();
if (!tmp.isEmpty()) {
QFile f(tmp);
@ -445,7 +445,7 @@ QString MuseScore::createDefaultName() const
else
tmpName = QString("%1-%2").arg(name).arg(n);
foreach(Score* s, scoreList) {
if (s->name() == tmpName) {
if (s->fileInfo()->completeBaseName() == tmpName) {
nameExists = true;
break;
}
@ -1468,7 +1468,7 @@ void MuseScore::printFile()
if (!printerDev.setPageMargins(QMarginsF()))
qDebug("unable to clear printer margins");
printerDev.setColorMode(QPrinter::Color);
printerDev.setDocName(cs->name());
printerDev.setDocName(cs->fileInfo()->completeBaseName());
printerDev.setOutputFormat(QPrinter::NativeFormat);
int pages = cs->pages().size();
printerDev.setFromTo(1, pages);
@ -1478,7 +1478,7 @@ void MuseScore::printFile()
#else
// when setting this on windows platform, pd.exec() does not
// show dialog
printerDev.setOutputFileName(cs->masterScore()->fileInfo()->path() + "/" + cs->name() + ".pdf");
printerDev.setOutputFileName(cs->masterScore()->fileInfo()->path() + "/" + cs->fileInfo()->completeBaseName() + ".pdf");
#endif
QPrintDialog pd(&printerDev, 0);
@ -1567,16 +1567,16 @@ void MuseScore::exportFile()
#ifdef Q_OS_WIN
if (QSysInfo::WindowsVersion == QSysInfo::WV_XP) {
if (!cs->isMaster())
name = QString("%1/%2-%3").arg(saveDirectory).arg(cs->masterScore()->name()).arg(createDefaultFileName(cs->name()));
name = QString("%1/%2-%3").arg(saveDirectory).arg(cs->masterScore()->fileInfo()->completeBaseName()).arg(createDefaultFileName(cs->name()));
else
name = QString("%1/%2").arg(saveDirectory).arg(cs->name());
name = QString("%1/%2").arg(saveDirectory).arg(cs->fileInfo()->completeBaseName());
}
else
#endif
if (!cs->isMaster())
name = QString("%1/%2-%3.%4").arg(saveDirectory).arg(cs->masterScore()->name()).arg(createDefaultFileName(cs->name())).arg(saveFormat);
name = QString("%1/%2-%3.%4").arg(saveDirectory).arg(cs->masterScore()->fileInfo()->completeBaseName()).arg(createDefaultFileName(cs->fileInfo()->completeBaseName())).arg(saveFormat);
else
name = QString("%1/%2.%3").arg(saveDirectory).arg(cs->name()).arg(saveFormat);
name = QString("%1/%2.%3").arg(saveDirectory).arg(cs->fileInfo()->completeBaseName()).arg(saveFormat);
int idx = fl.indexOf(QRegExp(".+\\(\\*\\." + saveFormat + "\\)"), Qt::CaseInsensitive);
if (idx != -1)
@ -1644,7 +1644,7 @@ bool MuseScore::exportParts()
if (saveFormat.isEmpty())
saveFormat = "pdf";
QString scoreName = cs->isMaster() ? cs->name() : cs->masterScore()->name();
QString scoreName = (cs->isMaster() ? cs : cs->masterScore())->fileInfo()->completeBaseName();
QString name;
#ifdef Q_OS_WIN
if (QSysInfo::WindowsVersion == QSysInfo::WV_XP)
@ -1680,7 +1680,7 @@ bool MuseScore::exportParts()
QString skipMessage = tr("Skip");
foreach (Excerpt* e, thisScore->excerpts()) {
Score* pScore = e->partScore();
QString partfn = fi.absolutePath() + QDir::separator() + fi.completeBaseName() + "-" + createDefaultFileName(pScore->name()) + "." + ext;
QString partfn = fi.absolutePath() + QDir::separator() + fi.completeBaseName() + "-" + createDefaultFileName(pScore->fileInfo()->completeBaseName()) + "." + ext;
QFileInfo fip(partfn);
if(fip.exists() && !overwrite) {
if(noToAll)
@ -1773,7 +1773,7 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy, const QString& path, const QStr
if (rv && !saveCopy) {
cs->masterScore()->fileInfo()->setFile(fn);
setWindowTitle("MuseScore: " + cs->name());
setWindowTitle("MuseScore: " + cs->fileInfo()->completeBaseName());
cs->undoStack()->setClean();
dirtyChanged(cs);
cs->setCreated(false);
@ -1872,7 +1872,7 @@ bool MuseScore::savePdf(Score* cs, const QString& saveName)
printerDev.setCreator("MuseScore Version: " VERSION);
if (!printerDev.setPageMargins(QMarginsF()))
qDebug("unable to clear printer margins");
printerDev.setTitle(cs->name());
printerDev.setTitle(cs->fileInfo()->completeBaseName());
QPainter p;
if (!p.begin(&printerDev))
@ -1912,7 +1912,7 @@ bool MuseScore::savePdf(QList<Score*> cs, const QString& saveName)
if (!printerDev.setPageMargins(QMarginsF()))
qDebug("unable to clear printer margins");
printerDev.setColorMode(QPrinter::Color);
printerDev.setDocName(firstScore->name());
printerDev.setDocName(firstScore->fileInfo()->completeBaseName());
printerDev.setOutputFormat(QPrinter::PdfFormat);
printerDev.setOutputFileName(saveName);
@ -2088,6 +2088,7 @@ Score::FileError readScore(MasterScore* score, QString name, bool ignoreVersionE
score->updateChannel();
score->setSaved(false);
score->update();
if (!ignoreVersionError && !MScore::noGui)
if (!score->sanityCheck(QString()))
return Score::FileError::FILE_CORRUPTED;
@ -2128,16 +2129,16 @@ bool MuseScore::saveAs(Score* cs, bool saveCopy)
#ifdef Q_OS_WIN
if (QSysInfo::WindowsVersion == QSysInfo::WV_XP) {
if (!cs->isMaster())
name = QString("%1/%2-%3").arg(saveDirectory).arg(cs->masterScore()->name()).arg(createDefaultFileName(cs->name()));
name = QString("%1/%2-%3").arg(saveDirectory).arg(cs->masterScore()->fileInfo()->completeBaseName()).arg(createDefaultFileName(cs->fileInfo()->completeBaseName()));
else
name = QString("%1/%2").arg(saveDirectory).arg(cs->name());
name = QString("%1/%2").arg(saveDirectory).arg(cs->fileInfo()->completeBaseName());
}
else
#endif
if (!cs->isMaster())
name = QString("%1/%2-%3.mscz").arg(saveDirectory).arg(cs->masterScore()->name()).arg(createDefaultFileName(cs->name()));
name = QString("%1/%2-%3.mscz").arg(saveDirectory).arg(cs->masterScore()->fileInfo()->completeBaseName()).arg(createDefaultFileName(cs->fileInfo()->completeBaseName()));
else
name = QString("%1/%2.mscz").arg(saveDirectory).arg(cs->name());
name = QString("%1/%2.mscz").arg(saveDirectory).arg(cs->fileInfo()->completeBaseName());
QString filter = fl.join(";;");
QString fn = mscore->getSaveScoreName(saveDialogTitle, name, filter);
@ -2181,7 +2182,7 @@ bool MuseScore::saveSelection(Score* cs)
if (saveDirectory.isEmpty())
saveDirectory = preferences.myScoresPath;
QString name = QString("%1/%2.mscz").arg(saveDirectory).arg(cs->name());
QString name = QString("%1/%2.mscz").arg(saveDirectory).arg(cs->fileInfo()->completeBaseName());
QString filter = fl.join(";;");
QString fn = mscore->getSaveScoreName(saveDialogTitle, name, filter);
if (fn.isEmpty())

View file

@ -1286,13 +1286,13 @@ void MuseScore::updateTabNames()
for (int i = 0; i < tab1->count(); ++i) {
ScoreView* view = tab1->view(i);
if (view)
tab1->setTabText(i, view->score()->name());
tab1->setTabText(i, view->score()->fileInfo()->completeBaseName());
}
if (tab2) {
for (int i = 0; i < tab2->count(); ++i) {
ScoreView* view = tab2->view(i);
if (view)
tab2->setTabText(i, view->score()->name());
tab2->setTabText(i, view->score()->fileInfo()->completeBaseName());
}
}
}
@ -1462,9 +1462,10 @@ void MuseScore::setCurrentScoreView(ScoreView* view)
}
if (!cs->isMaster())
setWindowTitle(MUSESCORE_NAME_VERSION ": " + cs->masterScore()->name() + "-" + cs->name());
setWindowTitle(MUSESCORE_NAME_VERSION ": " + cs->masterScore()->fileInfo()->completeBaseName()
+ "-" + cs->fileInfo()->completeBaseName());
else
setWindowTitle(MUSESCORE_NAME_VERSION ": " + cs->name());
setWindowTitle(MUSESCORE_NAME_VERSION ": " + cs->fileInfo()->completeBaseName());
QAction* a = getAction("concert-pitch");
a->setChecked(cs->styleB(StyleIdx::concertPitch));
@ -3003,7 +3004,7 @@ void MuseScore::dirtyChanged(Score* s)
qDebug("score not in list");
return;
}
QString label(score->masterScore()->name());
QString label(score->fileInfo()->completeBaseName());
if (score->dirty())
label += "*";
tab1->setTabText(idx, label);
@ -4051,7 +4052,7 @@ void MuseScore::endCmd()
excerptsChanged(cs->masterScore());
cs->masterScore()->setExcerptsChanged(false);
}
if (cs->instrumentsChanged()) {
if (cs->masterScore()->instrumentsChanged()) {
if (!noSeq && (seq && seq->isRunning()))
seq->initInstruments();
instrumentChanged(); // update mixer

View file

@ -251,7 +251,7 @@ void PianorollEditor::setStaff(Staff* st)
}
staff = st;
if (staff) {
setWindowTitle(tr("MuseScore: <%1> Staff: %2").arg(_score->name()).arg(st->idx()));
setWindowTitle(tr("MuseScore: <%1> Staff: %2").arg(_score->fileInfo()->completeBaseName()).arg(st->idx()));
TempoMap* tl = _score->tempomap();
TimeSigMap* sl = _score->sigmap();
for (int i = 0; i < 3; ++i)

View file

@ -40,7 +40,7 @@ QAccessible::Role AccessibleScoreView::role() const{
QString AccessibleScoreView::text(QAccessible::Text t) const {
switch (t) {
case QAccessible::Name:
return tr("Score %1").arg(s->score()->name());
return tr("Score %1").arg(s->score()->fileInfo()->completeBaseName());
case QAccessible::Value:
return s->score()->accessibleInfo();
default:

View file

@ -206,9 +206,9 @@ void ScoreTab::setCurrent(int n)
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty()) {
tab2->blockSignals(true);
tab2->addTab(score->name().replace("&","&&"));
tab2->addTab(score->fileInfo()->completeBaseName().replace("&","&&"));
foreach(const Excerpt* excerpt, excerpts) {
tab2->addTab(excerpt->partScore()->name().replace("&","&&"));
tab2->addTab(excerpt->partScore()->fileInfo()->completeBaseName().replace("&","&&"));
}
tab2->setCurrentIndex(tsv->part);
tab2->blockSignals(false);
@ -254,9 +254,9 @@ void ScoreTab::updateExcerpts()
QList<Excerpt*>& excerpts = score->excerpts();
if (!excerpts.isEmpty()) {
tab2->blockSignals(true);
tab2->addTab(score->name().replace("&","&&"));
tab2->addTab(score->fileInfo()->completeBaseName().replace("&","&&"));
foreach(const Excerpt* excerpt, excerpts)
tab2->addTab(excerpt->partScore()->name().replace("&","&&"));
tab2->addTab(excerpt->partScore()->fileInfo()->completeBaseName().replace("&","&&"));
tab2->blockSignals(false);
tab2->setVisible(true);
@ -311,7 +311,7 @@ void ScoreTab::insertTab(Score* s)
{
int idx = scoreList->indexOf(s->masterScore());
tab->blockSignals(true);
tab->insertTab(idx, s->name().replace("&","&&"));
tab->insertTab(idx, s->fileInfo()->completeBaseName().replace("&","&&"));
tab->setTabData(idx, QVariant::fromValue<void*>(new TabScoreView(s)));
tab->blockSignals(false);
}

View file

@ -4277,6 +4277,7 @@ bool ScoreView::event(QEvent* event)
void ScoreView::startUndoRedo()
{
// _score->initCmd();
// exit edit mode
if (sm->configuration().contains(states[EDIT]))
sm->postEvent(new CommandEvent("escape"));

View file

@ -101,8 +101,8 @@ void SelectionWindow::changeCheckbox(QListWidgetItem* item)
if (_score->selection().isRange())
_score->selection().updateSelectedElements();
updateFilteredElements();
_score->setUpdateAll();
_score->end();
// _score->setUpdateAll();
// _score->end();
ScoreAccessibility::instance()->updateAccessibilityInfo();
}

View file

@ -1,5 +1,6 @@
====================================================================
MuseScore Version 3 design goals/changes
Remarks for MuseScore Version 3
design goals/changes
====================================================================
- Optimize horizontal layout by allowing overlapping segments.
@ -9,8 +10,11 @@
- Automatically increase vertical space between staves to avoid collisions.
- Use the segment shapes to compute the minimum distance between staves.
Use the minimum distance if its bigger than the style distance;
- Implement a way to (re-)layout only the modified part of the score.
A reorganization of layout is needed for this. Layout should work in one pass in
an incremental way.
- Do not allow more than one System on a line. In 2.x a horizontal box splits
a line into two systems. In 3.x a horizontal box is handled as a special measure.
@ -21,18 +25,16 @@
- Do not undo/redo add/removal of "created" elements.
- It speeds up doLayout() and consumes less memory.
? layout of parts after change in one part not necessary
- incomplete layouts should be possible (layout only up to first page
to speed up program start)
In 2.x all Segments must be on the undo/redo stack to keep the history
In 2.x all Segments changes must be on the undo/redo stack to keep the history
consistent, This was necessary as Segments were referring to
previous/next segments to find the proper insertion point.
In 3.x Undo knows were to (re-)insert Segments by only checking type and tick
position.
- evaluate the possibility of implementing "Continuous View" as a real "view" change
without changing the score (no undo/redo change)
- remove pre 2.0 compatibility
@ -70,7 +72,14 @@
- use list.empty() instead of list.isEmpty()
- etc.
(see https://marcmutz.wordpress.com/effective-qt/containers/)
(see https://marcmutz.wordpress.com/effective-qt/containers/)
Caution when replacing Qt container with stl container as the semantic
may be different. Especially in a "for (xxx : yyy)" loop the Qt container
is copied (copy on write) and the stl container not. That meauns that you can modify a
Qt container (inserting/deleting elements) in this for loop. This will usually not
work for a stl container.
* In iterating a SegmentList instead of
for (Segment* s = segments->first(); s; s = s->next())
@ -93,6 +102,53 @@
Goal is to allow
- allow type conversion (to QVariant for example)
- add conversion to/from string for use in Xml::read(...)/Xml::write(xxx)
- export to qml scripting
Drawbacks:
- forward declaration is not possible as for c++11 "enum class"
- the enum _Direction is a different type than Direction; which sometimes
require a static_cast
This is somehow experimental.
* debug messages
- use qWarning(), qCritical() and qFatal()
- if debug messages are used, it should be possible to switch them off and they
should be removed in release mode
- don't use qDebug(), instead use a log category and call qCDebug(logCategory, ...)
(see undo.h undo.cpp for example usage)
TODO: check if they can be removed in system mode
====================================================================
some rules
====================================================================
Layout
- After loading a score, the score data can only be modified in a "undo" function during editing.
The score is "dirty" if there is an undo stack entry.
- Flags/data which describe what kind of relayout/update the score needs are collected in
Score->CmdState. They can only be set in an "undo" function.
Score File
- "created" elements are not written out into the score file. For example bar lines are usually created
by layout. They are marked as created and therefore do not appear in the score file.
- Element properties are only written if they differ from their default value which usually is the
style value if they are styled.
====================================================================
implementation details
====================================================================
* why do we need to layout MasterScore and all parts?
Layout can remove elements which are user modified for example spanner segments.
This needs to be undoable. Layout cannot be delayed bc. we then cannot associate
any changes to the proper command frame in the undo stack.
====================================================================

View file

@ -123,7 +123,7 @@ else (APPLE)
set(CMAKE_CXX_FLAGS_RELEASE "-std=gnu++0x -mno-ms-bitfields -O2 -DNDEBUG -DQT_NO_DEBUG")
else (MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-std=gnu++0x -fPIC -fPIE -g")
set(CMAKE_CXX_FLAGS_RELEASE "-std=gnu++0x -fPIC -O2 -DNDEBUG -DQT_NO_DEBUG")
set(CMAKE_CXX_FLAGS_RELEASE "-std=gnu++0x -fPIC -O2 -DNDEBUG -DQT_NO_DEBUG -DQT_NO_DEBUG_OUTPUT")
endif (MINGW)
endif(APPLE)

View file

@ -24,7 +24,7 @@ const char* tests[] = {
"libmscore/keysig/tst_keysig",
"libmscore/barline/tst_barline",
"libmscore/clef/tst_clef",
// "libmscore/timesig/tst_timesig",
/**/ "libmscore/timesig/tst_timesig",
"libmscore/repeat/tst_repeat",
"libmscore/dynamic/tst_dynamic",
"libmscore/breath/tst_breath",
@ -52,7 +52,7 @@ const char* tests[] = {
// "libmscore/earlymusic/tst_earlymusic",
// "libmscore/midi/tst_midi",
// "libmscore/tools/tst_tools",
"libmscore/tools/tst_tools",
// "libmscore/splitstaff/tst_splitstaff",
// "libmscore/split/tst_split",
"libmscore/plugins/tst_plugins",

View file

@ -68,7 +68,9 @@ SRC=" \
grace-2
harmony-12\
user-offset-2 \
system-4"
"
# layout-1 layout-2
# system-4"
DPI=130
F=vtest.html