1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2002-2012 Werner Schweer
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License version 2
9 // as published by the Free Software Foundation and appearing in
10 // the file LICENCE.GPL
11 //=============================================================================
12
13 #include "score.h"
14 #include "measure.h"
15 #include "undo.h"
16 #include "range.h"
17 #include "spanner.h"
18
19 namespace Ms {
20
21 //---------------------------------------------------------
22 // cmdJoinMeasure
23 // join measures from m1 upto (including) m2
24 //---------------------------------------------------------
25
cmdJoinMeasure(Measure * m1,Measure * m2)26 void Score::cmdJoinMeasure(Measure* m1, Measure* m2)
27 {
28 if (!m1 || !m2)
29 return;
30 if (m1->isMMRest())
31 m1 = m1->mmRestFirst();
32 if (m2->isMMRest())
33 m2 = m2->mmRestLast();
34 startCmd();
35
36 deselectAll();
37
38 ScoreRange range;
39 range.read(m1->first(), m2->last());
40
41 Fraction tick1 = m1->tick();
42 Fraction tick2 = m2->endTick();
43
44 auto spanners = _spanner.findContained(tick1.ticks(), tick2.ticks());
45 for (auto i : spanners)
46 undo(new RemoveElement(i.value));
47
48 for (auto i : spanner()) {
49 Spanner* s = i.second;
50 if (s->tick() >= tick1 && s->tick() < tick2)
51 s->setStartElement(0);
52 if (s->tick2() >= tick1 && s->tick2() < tick2)
53 s->setEndElement(0);
54 }
55
56 deleteMeasures(m1, m2, true);
57
58 MeasureBase* next = m2->next();
59 const Fraction newTimesig = m1->timesig();
60 Fraction newLen;
61 for (Measure* mm = m1; mm; mm = mm->nextMeasure()) {
62 newLen += mm->ticks();
63 if (mm == m2)
64 break;
65 }
66 insertMeasure(ElementType::MEASURE, next, /* createEmptyMeasures*/ true);
67 // The loop since measures are not currently linked in MuseScore
68 for (Score* s : masterScore()->scoreList()) {
69 Measure* ins = s->tick2measure(tick1);
70 ins->undoChangeProperty(Pid::TIMESIG_NOMINAL, newTimesig);
71 // TODO: there was a commented chunk of code regarding setting bar
72 // line types. Should we handle them here too?
73 // m->setEndBarLineType(m2->endBarLineType(), m2->endBarLineGenerated(),
74 // m2->endBarLineVisible(), m2->endBarLineColor());
75 }
76 Measure* inserted = (next ? next->prevMeasure() : lastMeasure());
77 inserted->adjustToLen(newLen, /* appendRests... */ false);
78
79 range.write(this, m1->tick());
80
81 endCmd();
82 }
83
84 }
85
86