1 //=============================================================================
2 // MuseScore
3 // Music Composition & Notation
4 //
5 // Copyright (C) 2019 Werner Schweer and others
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 "cursor.h"
15 #include "elements.h"
16 #include "libmscore/instrtemplate.h"
17 #include "libmscore/measure.h"
18 #include "libmscore/score.h"
19 #include "libmscore/segment.h"
20 #include "libmscore/text.h"
21
22 #include "musescore.h"
23 #include "../qmlpluginengine.h"
24
25 namespace Ms {
26 namespace PluginAPI {
27
28 //---------------------------------------------------------
29 // Score::newCursor
30 //---------------------------------------------------------
31
newCursor()32 Cursor* Score::newCursor()
33 {
34 return new Cursor(score());
35 }
36
37 //---------------------------------------------------------
38 // Score::addText
39 /// \brief Adds a header text to the score.
40 /// \param type One of the following values:
41 /// - "title"
42 /// - "subtitle"
43 /// - "composer"
44 /// - "lyricist"
45 /// - Any other value corresponds to default text style.
46 /// \param txt Text to be added.
47 //---------------------------------------------------------
48
addText(const QString & type,const QString & txt)49 void Score::addText(const QString& type, const QString& txt)
50 {
51 MeasureBase* measure = score()->first();
52 if (!measure || !measure->isVBox()) {
53 score()->insertMeasure(ElementType::VBOX, measure);
54 measure = score()->first();
55 }
56 Tid tid = Tid::DEFAULT;
57 if (type == "title")
58 tid = Tid::TITLE;
59 else if (type == "subtitle")
60 tid = Tid::SUBTITLE;
61 else if (type == "composer")
62 tid = Tid::COMPOSER;
63 else if (type == "lyricist")
64 tid = Tid::POET;
65
66 Ms::Text* text = new Ms::Text(score(), tid);
67 text->setParent(measure);
68 text->setXmlText(txt);
69 score()->undoAddElement(text);
70 }
71
72 //---------------------------------------------------------
73 // defaultInstrTemplate
74 //---------------------------------------------------------
75
defaultInstrTemplate()76 static const InstrumentTemplate* defaultInstrTemplate()
77 {
78 static InstrumentTemplate defaultInstrument;
79 if (defaultInstrument.channel.empty()) {
80 Channel a;
81 a.setChorus(0);
82 a.setReverb(0);
83 a.setName(Channel::DEFAULT_NAME);
84 a.setBank(0);
85 a.setVolume(90);
86 a.setPan(0);
87 defaultInstrument.channel.append(a);
88 }
89 return &defaultInstrument;
90 }
91
92 //---------------------------------------------------------
93 // instrTemplateFromName
94 //---------------------------------------------------------
95
instrTemplateFromName(const QString & name)96 const InstrumentTemplate* Score::instrTemplateFromName(const QString& name)
97 {
98 const InstrumentTemplate* t = searchTemplate(name);
99 if (!t) {
100 qWarning("<%s> not found", qPrintable(name));
101 t = defaultInstrTemplate();
102 }
103 return t;
104 }
105
106 //---------------------------------------------------------
107 // Score::appendPart
108 //---------------------------------------------------------
109
appendPart(const QString & instrumentId)110 void Score::appendPart(const QString& instrumentId)
111 {
112 const InstrumentTemplate* t = searchTemplate(instrumentId);
113
114 if (!t) {
115 qWarning("appendPart: <%s> not found", qPrintable(instrumentId));
116 t = defaultInstrTemplate();
117 }
118
119 score()->appendPart(t);
120 }
121
122 //---------------------------------------------------------
123 // Score::appendPartByMusicXmlId
124 //---------------------------------------------------------
125
appendPartByMusicXmlId(const QString & instrumentMusicXmlId)126 void Score::appendPartByMusicXmlId(const QString& instrumentMusicXmlId)
127 {
128 const InstrumentTemplate* t = searchTemplateForMusicXmlId(instrumentMusicXmlId);
129
130 if (!t) {
131 qWarning("appendPart: <%s> not found", qPrintable(instrumentMusicXmlId));
132 t = defaultInstrTemplate();
133 }
134
135 score()->appendPart(t);
136 }
137
138 //---------------------------------------------------------
139 // Score::firstSegment
140 //---------------------------------------------------------
141
firstSegment()142 Segment* Score::firstSegment()
143 {
144 return wrap<Segment>(score()->firstSegment(Ms::SegmentType::All), Ownership::SCORE);
145 }
146
147 //---------------------------------------------------------
148 // Score::lastSegment
149 //---------------------------------------------------------
150
lastSegment()151 Segment* Score::lastSegment()
152 {
153 return wrap<Segment>(score()->lastSegment(), Ownership::SCORE);
154 }
155
156 //---------------------------------------------------------
157 // Score::firstMeasure
158 //---------------------------------------------------------
159
firstMeasure()160 Measure* Score::firstMeasure()
161 {
162 return wrap<Measure>(score()->firstMeasure(), Ownership::SCORE);
163 }
164
165 //---------------------------------------------------------
166 // Score::firstMeasureMM
167 //---------------------------------------------------------
168
firstMeasureMM()169 Measure* Score::firstMeasureMM()
170 {
171 return wrap<Measure>(score()->firstMeasureMM(), Ownership::SCORE);
172 }
173
174 //---------------------------------------------------------
175 // Score::lastMeasure
176 //---------------------------------------------------------
177
lastMeasure()178 Measure* Score::lastMeasure()
179 {
180 return wrap<Measure>(score()->lastMeasure(), Ownership::SCORE);
181 }
182 //---------------------------------------------------------
183 // Score::firstMeasureMM
184 //---------------------------------------------------------
185
lastMeasureMM()186 Measure* Score::lastMeasureMM()
187 {
188 return wrap<Measure>(score()->lastMeasureMM(), Ownership::SCORE);
189 }
190
191 //---------------------------------------------------------
192 // Score::staves
193 //---------------------------------------------------------
194
staves()195 QQmlListProperty<Staff> Score::staves()
196 {
197 return wrapContainerProperty<Staff>(this, score()->staves());
198 }
199
200 //---------------------------------------------------------
201 // Score::startCmd
202 //---------------------------------------------------------
203
startCmd()204 void Score::startCmd()
205 {
206 // TODO: should better use qmlEngine(this) (need to set context for wrappers then)
207 const QmlPluginEngine* engine = mscore->getPluginEngine();
208 if (engine->inScoreChangeActionHandler()) {
209 // Plugin-originated changes made while handling onScoreStateChanged
210 // should be grouped together with the action which caused this change
211 // (if it was caused by actual score change).
212 if (!score()->undoStack()->active())
213 score()->undoStack()->reopen();
214 }
215 else {
216 score()->startCmd();
217 }
218 }
219 }
220 }
221