Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-Studio-CLA-applies
4 : *
5 : * MuseScore Studio
6 : * Music Composition & Notation
7 : *
8 : * Copyright (C) 2021 MuseScore Limited and others
9 : *
10 : * This program is free software: you can redistribute it and/or modify
11 : * it under the terms of the GNU General Public License version 3 as
12 : * published by the Free Software Foundation.
13 : *
14 : * This program is distributed in the hope that it will be useful,
15 : * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : * GNU General Public License for more details.
18 : *
19 : * You should have received a copy of the GNU General Public License
20 : * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include "mcursor.h"
24 :
25 : #include "compat/scoreaccess.h"
26 :
27 : #include "chord.h"
28 : #include "durationtype.h"
29 : #include "factory.h"
30 : #include "instrtemplate.h"
31 : #include "keysig.h"
32 : #include "masterscore.h"
33 : #include "measure.h"
34 : #include "note.h"
35 : #include "part.h"
36 : #include "segment.h"
37 : #include "staff.h"
38 : #include "timesig.h"
39 : #include "sig.h"
40 :
41 : #include "log.h"
42 :
43 : using namespace mu;
44 : using namespace mu::engraving;
45 :
46 : namespace mu::engraving {
47 : //---------------------------------------------------------
48 : // MCursor
49 : //---------------------------------------------------------
50 :
51 3 : MCursor::MCursor(MasterScore* s)
52 : {
53 3 : m_score = s;
54 3 : move(0, Fraction(0, 1));
55 3 : }
56 :
57 : //---------------------------------------------------------
58 : // createMeasures
59 : //---------------------------------------------------------
60 :
61 7 : void MCursor::createMeasures()
62 : {
63 : Measure* measure;
64 : for (;;) {
65 10 : Fraction tick = Fraction(0, 1);
66 10 : measure = m_score->lastMeasure();
67 10 : if (measure) {
68 7 : tick = measure->endTick();
69 7 : if (tick > m_tick) {
70 7 : break;
71 : }
72 : }
73 3 : measure = Factory::createMeasure(m_score);
74 3 : measure->setTick(tick);
75 3 : measure->setTimesig(m_sig);
76 3 : measure->setTicks(m_sig);
77 3 : m_score->measures()->append(measure);
78 3 : }
79 7 : }
80 :
81 : //---------------------------------------------------------
82 : // addChord
83 : //---------------------------------------------------------
84 :
85 3 : Chord* MCursor::addChord(int pitch, const TDuration& duration)
86 : {
87 3 : createMeasures();
88 3 : Measure* measure = m_score->tick2measure(m_tick);
89 3 : Segment* segment = measure->getSegment(SegmentType::ChordRest, m_tick);
90 3 : Chord* chord = toChord(segment->element(m_track));
91 3 : if (chord == 0) {
92 3 : chord = Factory::createChord(segment);
93 3 : chord->setTrack(m_track);
94 3 : chord->setDurationType(duration);
95 3 : chord->setTicks(duration.fraction());
96 3 : segment->add(chord);
97 : }
98 3 : Note* note = Factory::createNote(chord);
99 3 : chord->add(note);
100 3 : note->setPitch(pitch);
101 3 : note->setTpcFromPitch();
102 3 : m_tick += duration.ticks();
103 3 : return chord;
104 : }
105 :
106 : //---------------------------------------------------------
107 : // addKeySig
108 : //---------------------------------------------------------
109 :
110 2 : void MCursor::addKeySig(Key key)
111 : {
112 2 : createMeasures();
113 2 : Measure* measure = m_score->tick2measure(m_tick);
114 2 : Segment* segment = measure->getSegment(SegmentType::KeySig, m_tick);
115 2 : size_t n = m_score->nstaves();
116 4 : for (staff_idx_t i = 0; i < n; ++i) {
117 2 : KeySig* ks = Factory::createKeySig(segment);
118 2 : ks->setKey(key);
119 2 : ks->setTrack(i * VOICES);
120 2 : segment->add(ks);
121 : }
122 2 : }
123 :
124 : //---------------------------------------------------------
125 : // addTimeSig
126 : //---------------------------------------------------------
127 :
128 2 : TimeSig* MCursor::addTimeSig(const Fraction& f)
129 : {
130 2 : createMeasures();
131 2 : Measure* measure = m_score->tick2measure(m_tick);
132 2 : Segment* segment = measure->getSegment(SegmentType::TimeSig, m_tick);
133 2 : TimeSig* ts = 0;
134 4 : for (size_t i = 0; i < m_score->nstaves(); ++i) {
135 2 : ts = Factory::createTimeSig(segment);
136 2 : ts->setSig(f, TimeSigType::NORMAL);
137 2 : ts->setTrack(i * VOICES);
138 2 : segment->add(ts);
139 : }
140 2 : m_score->sigmap()->add(m_tick.ticks(), SigEvent(f));
141 2 : return ts;
142 : }
143 :
144 : //---------------------------------------------------------
145 : // createScore
146 : //---------------------------------------------------------
147 :
148 3 : void MCursor::createScore(const muse::modularity::ContextPtr& iocCtx, const String& /*name*/)
149 : {
150 3 : delete m_score;
151 3 : m_score = compat::ScoreAccess::createMasterScoreWithBaseStyle(iocCtx);
152 : // TODO: set path/filename
153 3 : NOT_IMPLEMENTED;
154 3 : move(0, Fraction(0, 1));
155 3 : }
156 :
157 : //---------------------------------------------------------
158 : // move
159 : //---------------------------------------------------------
160 :
161 9 : void MCursor::move(int t, const Fraction& tick)
162 : {
163 9 : m_track = t;
164 9 : m_tick = tick;
165 9 : }
166 :
167 : //---------------------------------------------------------
168 : // addPart
169 : //---------------------------------------------------------
170 :
171 3 : void MCursor::addPart(const String& instrument)
172 : {
173 3 : Part* part = new Part(m_score);
174 3 : Staff* staff = Factory::createStaff(part);
175 3 : const InstrumentTemplate* it = searchTemplate(instrument);
176 3 : IF_ASSERT_FAILED(it) {
177 0 : return;
178 : }
179 :
180 3 : part->initFromInstrTemplate(it);
181 3 : m_score->appendPart(part);
182 3 : m_score->insertStaff(staff, 0);
183 3 : staff->init(it, 0, 0);
184 : }
185 : }
|