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) 2025 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 "editstaff.h"
24 :
25 : #include "../dom/guitarbend.h"
26 : #include "../dom/masterscore.h"
27 : #include "../dom/measure.h"
28 : #include "../dom/score.h"
29 : #include "../dom/staff.h"
30 : #include "../dom/stafflines.h"
31 : #include "../dom/stafftype.h"
32 :
33 : using namespace mu::engraving;
34 :
35 : //---------------------------------------------------------
36 : // InsertStaff
37 : //---------------------------------------------------------
38 :
39 57 : InsertStaff::InsertStaff(Staff* p, staff_idx_t _ridx)
40 : {
41 57 : staff = p;
42 57 : ridx = _ridx;
43 57 : }
44 :
45 13 : void InsertStaff::undo()
46 : {
47 13 : staff->score()->removeStaff(staff);
48 13 : }
49 :
50 60 : void InsertStaff::redo()
51 : {
52 60 : staff->score()->insertStaff(staff, ridx);
53 60 : }
54 :
55 36 : void InsertStaff::cleanup(bool wasDone)
56 : {
57 36 : if (!wasDone) {
58 10 : delete staff;
59 10 : staff = nullptr;
60 : }
61 36 : }
62 :
63 : //---------------------------------------------------------
64 : // RemoveStaff
65 : //---------------------------------------------------------
66 :
67 23 : RemoveStaff::RemoveStaff(Staff* p)
68 : {
69 23 : staff = p;
70 23 : ridx = staff->rstaff();
71 23 : wasSystemObjectStaff = staff->isSystemObjectStaff();
72 23 : }
73 :
74 6 : void RemoveStaff::undo()
75 : {
76 6 : staff->score()->insertStaff(staff, ridx);
77 6 : if (wasSystemObjectStaff) {
78 0 : staff->score()->addSystemObjectStaff(staff);
79 : }
80 6 : }
81 :
82 24 : void RemoveStaff::redo()
83 : {
84 24 : staff->score()->removeStaff(staff);
85 24 : if (wasSystemObjectStaff) {
86 0 : staff->score()->removeSystemObjectStaff(staff);
87 : }
88 24 : }
89 :
90 8 : void RemoveStaff::cleanup(bool wasDone)
91 : {
92 8 : if (wasDone) {
93 3 : delete staff;
94 3 : staff = nullptr;
95 : }
96 8 : }
97 :
98 : //---------------------------------------------------------
99 : // AddSystemObjectStaff
100 : //---------------------------------------------------------
101 :
102 0 : AddSystemObjectStaff::AddSystemObjectStaff(Staff* s)
103 0 : : staff(s)
104 : {
105 0 : }
106 :
107 0 : void AddSystemObjectStaff::undo()
108 : {
109 0 : staff->score()->removeSystemObjectStaff(staff);
110 0 : }
111 :
112 0 : void AddSystemObjectStaff::redo()
113 : {
114 0 : staff->score()->addSystemObjectStaff(staff);
115 0 : }
116 :
117 : //---------------------------------------------------------
118 : // RemoveSystemObjectStaff
119 : //---------------------------------------------------------
120 :
121 0 : RemoveSystemObjectStaff::RemoveSystemObjectStaff(Staff* s)
122 0 : : staff(s)
123 : {
124 0 : }
125 :
126 0 : void RemoveSystemObjectStaff::undo()
127 : {
128 0 : staff->score()->addSystemObjectStaff(staff);
129 0 : }
130 :
131 0 : void RemoveSystemObjectStaff::redo()
132 : {
133 0 : staff->score()->removeSystemObjectStaff(staff);
134 0 : }
135 :
136 : //---------------------------------------------------------
137 : // InsertMStaff
138 : //---------------------------------------------------------
139 :
140 376 : InsertMStaff::InsertMStaff(Measure* m, MStaff* ms, staff_idx_t i)
141 : {
142 376 : measure = m;
143 376 : mstaff = ms;
144 376 : idx = i;
145 376 : }
146 :
147 71 : void InsertMStaff::undo()
148 : {
149 71 : measure->removeMStaff(mstaff, idx);
150 71 : }
151 :
152 441 : void InsertMStaff::redo()
153 : {
154 441 : measure->insertMStaff(mstaff, idx);
155 441 : }
156 :
157 : //---------------------------------------------------------
158 : // RemoveMStaff
159 : //---------------------------------------------------------
160 :
161 253 : RemoveMStaff::RemoveMStaff(Measure* m, MStaff* ms, int i)
162 : {
163 253 : measure = m;
164 253 : mstaff = ms;
165 253 : idx = i;
166 253 : }
167 :
168 65 : void RemoveMStaff::undo()
169 : {
170 65 : measure->insertMStaff(mstaff, idx);
171 65 : }
172 :
173 254 : void RemoveMStaff::redo()
174 : {
175 254 : measure->removeMStaff(mstaff, idx);
176 254 : }
177 :
178 : //---------------------------------------------------------
179 : // InsertStaves
180 : //---------------------------------------------------------
181 :
182 376 : InsertStaves::InsertStaves(Measure* m, staff_idx_t _a, staff_idx_t _b)
183 : {
184 376 : measure = m;
185 376 : a = _a;
186 376 : b = _b;
187 376 : }
188 :
189 71 : void InsertStaves::undo()
190 : {
191 71 : measure->removeStaves(a, b);
192 71 : }
193 :
194 441 : void InsertStaves::redo()
195 : {
196 441 : measure->insertStaves(a, b);
197 441 : }
198 :
199 : //---------------------------------------------------------
200 : // RemoveStaves
201 : //---------------------------------------------------------
202 :
203 253 : RemoveStaves::RemoveStaves(Measure* m, staff_idx_t _a, staff_idx_t _b)
204 : {
205 253 : measure = m;
206 253 : a = _a;
207 253 : b = _b;
208 253 : }
209 :
210 65 : void RemoveStaves::undo()
211 : {
212 65 : measure->insertStaves(a, b);
213 65 : }
214 :
215 254 : void RemoveStaves::redo()
216 : {
217 254 : measure->removeStaves(a, b);
218 254 : }
219 :
220 : //---------------------------------------------------------
221 : // SortStaves
222 : //---------------------------------------------------------
223 :
224 3 : SortStaves::SortStaves(Score* s, const std::vector<staff_idx_t>& l)
225 : {
226 3 : score = s;
227 :
228 10 : for (staff_idx_t i = 0; i < l.size(); i++) {
229 7 : rlist.push_back(muse::indexOf(l, i));
230 : }
231 3 : list = l;
232 3 : }
233 :
234 3 : void SortStaves::redo()
235 : {
236 3 : score->sortStaves(list);
237 3 : }
238 :
239 2 : void SortStaves::undo()
240 : {
241 2 : score->sortStaves(rlist);
242 2 : }
243 :
244 : //---------------------------------------------------------
245 : // ChangeStaff
246 : //---------------------------------------------------------
247 :
248 0 : ChangeStaff::ChangeStaff(Staff* _staff)
249 0 : : staff(_staff)
250 : {
251 0 : visible = staff->visible();
252 0 : clefType = staff->defaultClefType();
253 0 : userDist = staff->userDist();
254 0 : cutaway = staff->cutaway();
255 0 : hideSystemBarLine = staff->hideSystemBarLine();
256 0 : mergeMatchingRests = staff->mergeMatchingRests();
257 0 : reflectTranspositionInLinkedTab = staff->reflectTranspositionInLinkedTab();
258 0 : }
259 :
260 2 : ChangeStaff::ChangeStaff(Staff* _staff, bool _visible, ClefTypeList _clefType, Spatium _userDist, bool _cutaway, bool _hideSystemBarLine,
261 2 : AutoOnOff _mergeMatchingRests, bool _reflectTranspositionInLinkedTab)
262 : {
263 2 : staff = _staff;
264 2 : visible = _visible;
265 2 : clefType = _clefType;
266 2 : userDist = _userDist;
267 2 : cutaway = _cutaway;
268 2 : hideSystemBarLine = _hideSystemBarLine;
269 2 : mergeMatchingRests = _mergeMatchingRests;
270 2 : reflectTranspositionInLinkedTab = _reflectTranspositionInLinkedTab;
271 2 : }
272 :
273 : //---------------------------------------------------------
274 : // flip
275 : //---------------------------------------------------------
276 :
277 2 : void ChangeStaff::flip()
278 : {
279 2 : bool oldVisible = staff->visible();
280 2 : ClefTypeList oldClefType = staff->defaultClefType();
281 2 : Spatium oldUserDist = staff->userDist();
282 2 : bool oldCutaway = staff->cutaway();
283 2 : bool oldHideSystemBarLine = staff->hideSystemBarLine();
284 2 : AutoOnOff oldMergeMatchingRests = staff->mergeMatchingRests();
285 2 : bool oldReflectTranspositionInLinkedTab = staff->reflectTranspositionInLinkedTab();
286 :
287 2 : staff->setVisible(visible);
288 2 : staff->setDefaultClefType(clefType);
289 2 : staff->setUserDist(userDist);
290 2 : staff->setCutaway(cutaway);
291 2 : staff->setHideSystemBarLine(hideSystemBarLine);
292 2 : staff->setMergeMatchingRests(mergeMatchingRests);
293 2 : staff->setReflectTranspositionInLinkedTab(reflectTranspositionInLinkedTab);
294 :
295 2 : visible = oldVisible;
296 2 : clefType = oldClefType;
297 2 : userDist = oldUserDist;
298 2 : cutaway = oldCutaway;
299 2 : hideSystemBarLine = oldHideSystemBarLine;
300 2 : mergeMatchingRests = oldMergeMatchingRests;
301 2 : reflectTranspositionInLinkedTab = oldReflectTranspositionInLinkedTab;
302 :
303 2 : staff->triggerLayout();
304 2 : staff->masterScore()->rebuildMidiMapping();
305 2 : }
306 :
307 : //---------------------------------------------------------
308 : // ChangeStaffType::flip
309 : //---------------------------------------------------------
310 :
311 3 : void ChangeStaffType::flip()
312 : {
313 3 : StaffType oldStaffType = *staff->staffType(tick);
314 :
315 3 : staff->setStaffType(tick, staffType);
316 :
317 3 : bool invisibleChanged = oldStaffType.invisible() != staffType.invisible();
318 3 : bool fromTabToStandard = oldStaffType.isTabStaff() && !staffType.isTabStaff();
319 :
320 3 : staffType = oldStaffType;
321 :
322 3 : Score* score = staff->score();
323 3 : if (invisibleChanged) {
324 0 : staff_idx_t staffIdx = staff->idx();
325 0 : for (Measure* m = score->firstMeasure(); m; m = m->nextMeasure()) {
326 0 : m->staffLines(staffIdx)->setVisible(!staff->isLinesInvisible(tick));
327 : }
328 : }
329 :
330 3 : if (fromTabToStandard) {
331 0 : GuitarBend::adaptBendsFromTabToStandardStaff(staff);
332 : }
333 :
334 3 : staff->triggerLayout();
335 3 : }
336 :
337 : //---------------------------------------------------------
338 : // ChangeMStaffProperties
339 : //---------------------------------------------------------
340 :
341 0 : ChangeMStaffProperties::ChangeMStaffProperties(Measure* m, staff_idx_t i, bool v, bool s)
342 0 : : measure(m), staffIdx(i), visible(v), stemless(s)
343 : {
344 0 : }
345 :
346 0 : void ChangeMStaffProperties::flip()
347 : {
348 0 : bool v = measure->visible(staffIdx);
349 0 : bool s = measure->stemless(staffIdx);
350 0 : measure->setStaffVisible(staffIdx, visible);
351 0 : measure->setStaffStemless(staffIdx, stemless);
352 0 : visible = v;
353 0 : stemless = s;
354 0 : }
355 :
356 : //---------------------------------------------------------
357 : // ChangeMStaffHideIfEmpty
358 : //---------------------------------------------------------
359 :
360 0 : ChangeMStaffHideIfEmpty::ChangeMStaffHideIfEmpty(Measure* m, staff_idx_t i, AutoOnOff h)
361 0 : : measure(m), staffIdx(i), hideIfEmpty(h)
362 : {
363 0 : }
364 :
365 0 : void ChangeMStaffHideIfEmpty::flip()
366 : {
367 0 : AutoOnOff h = measure->hideStaffIfEmpty(staffIdx);
368 0 : measure->setHideStaffIfEmpty(staffIdx, hideIfEmpty);
369 0 : measure->triggerLayout(staffIdx);
370 0 : hideIfEmpty = h;
371 0 : }
|