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 "qmlpluginapi.h"
24 :
25 : #include <QQmlEngine>
26 : #include <QJSValueIterator>
27 :
28 : #include "engraving/compat/scoreaccess.h"
29 : #include "engraving/dom/factory.h"
30 : #include "engraving/dom/interval.h"
31 : #include "engraving/dom/masterscore.h"
32 : #include "engraving/types/types.h"
33 :
34 : #include "notation/inotation.h"
35 : #include "notation/inotationelements.h" // IWYU pragma: keep
36 : #include "notationscene/notationcommands.h"
37 :
38 : // api
39 : #include "engravingapiv1.h"
40 : #include "rcommand/commandtypes.h"
41 : #include "score.h"
42 : #include "instrument.h"
43 : #include "cursor.h"
44 : #include "elements.h"
45 : #include "selection.h"
46 : #include "util.h"
47 :
48 : #include "log.h"
49 :
50 : using namespace mu::engraving;
51 : using namespace mu::engraving::apiv1;
52 :
53 : Enum* PluginAPI::elementTypeEnum = nullptr;
54 : Enum* PluginAPI::accidentalTypeEnum = nullptr;
55 : Enum* PluginAPI::accidentalBracketEnum = nullptr;
56 : Enum* PluginAPI::ornamentStyleEnum = nullptr;
57 : Enum* PluginAPI::alignEnum = nullptr;
58 : Enum* PluginAPI::placementEnum = nullptr;
59 : Enum* PluginAPI::placementHEnum = nullptr;
60 : Enum* PluginAPI::textPlaceEnum = nullptr;
61 : Enum* PluginAPI::directionEnum = nullptr;
62 : Enum* PluginAPI::directionHEnum = nullptr;
63 : Enum* PluginAPI::orientationEnum = nullptr;
64 : Enum* PluginAPI::autoOnOffEnum = nullptr;
65 : Enum* PluginAPI::autoCustomHideEnum = nullptr;
66 : Enum* PluginAPI::voiceAssignmentEnum = nullptr;
67 : Enum* PluginAPI::spacerTypeEnum = nullptr;
68 : Enum* PluginAPI::layoutBreakTypeEnum = nullptr;
69 : Enum* PluginAPI::durationTypeEnum = nullptr;
70 : Enum* PluginAPI::noteValueTypeEnum = nullptr;
71 : Enum* PluginAPI::beamModeEnum = nullptr;
72 : Enum* PluginAPI::glissandoTypeEnum = nullptr;
73 : Enum* PluginAPI::glissandoStyleEnum = nullptr;
74 : Enum* PluginAPI::harmonyTypeEnum = nullptr;
75 : Enum* PluginAPI::harmonyVoicingEnum = nullptr;
76 : Enum* PluginAPI::hDurationEnum = nullptr;
77 : Enum* PluginAPI::frameTypeEnum = nullptr;
78 : Enum* PluginAPI::verticalAlignmentEnum = nullptr;
79 : Enum* PluginAPI::tremoloBarTypeEnum = nullptr;
80 : Enum* PluginAPI::preferSharpFlatEnum = nullptr;
81 : Enum* PluginAPI::noteHeadTypeEnum = nullptr;
82 : Enum* PluginAPI::noteHeadSchemeEnum = nullptr;
83 : Enum* PluginAPI::noteHeadGroupEnum = nullptr;
84 : Enum* PluginAPI::noteTypeEnum = nullptr;
85 : Enum* PluginAPI::playEventTypeEnum = nullptr;
86 : Enum* PluginAPI::segmentTypeEnum = nullptr;
87 : Enum* PluginAPI::barLineTypeEnum = nullptr;
88 : Enum* PluginAPI::tidEnum = nullptr;
89 : Enum* PluginAPI::lyricsSyllabicEnum = nullptr;
90 : Enum* PluginAPI::spannerAnchorEnum = nullptr;
91 : Enum* PluginAPI::mMRestRangeBracketTypeEnum = nullptr;
92 : Enum* PluginAPI::tupletNumberTypeEnum = nullptr;
93 : Enum* PluginAPI::tupletBracketTypeEnum = nullptr;
94 : Enum* PluginAPI::tripletFeelTypeEnum = nullptr;
95 : Enum* PluginAPI::guitarBendTypeEnum = nullptr;
96 : Enum* PluginAPI::guitarBendShowHoldLineEnum = nullptr;
97 : Enum* PluginAPI::clefTypeEnum = nullptr;
98 : Enum* PluginAPI::clefToBarlinePositionEnum = nullptr;
99 : Enum* PluginAPI::dynamicTypeEnum = nullptr;
100 : Enum* PluginAPI::dynamicSpeedEnum = nullptr;
101 : Enum* PluginAPI::lineTypeEnum = nullptr;
102 : Enum* PluginAPI::hookTypeEnum = nullptr;
103 : Enum* PluginAPI::keyModeEnum = nullptr;
104 : Enum* PluginAPI::arpeggioTypeEnum = nullptr;
105 : Enum* PluginAPI::intervalStepEnum = nullptr;
106 : Enum* PluginAPI::intervalTypeEnum = nullptr;
107 : Enum* PluginAPI::instrumentLabelVisibilityEnum = nullptr;
108 : Enum* PluginAPI::ornamentShowAccidentalEnum = nullptr;
109 : Enum* PluginAPI::partialSpannerDirectionEnum = nullptr;
110 : Enum* PluginAPI::chordStylePresetEnum = nullptr;
111 : Enum* PluginAPI::playingTechniqueTypeEnum = nullptr;
112 : Enum* PluginAPI::gradualTempoChangeTypeEnum = nullptr;
113 : Enum* PluginAPI::changeMethodEnum = nullptr;
114 : Enum* PluginAPI::changeDirectionEnum = nullptr;
115 : Enum* PluginAPI::accidentalRoleEnum = nullptr;
116 : Enum* PluginAPI::accidentalValEnum = nullptr;
117 : Enum* PluginAPI::fermataTypeEnum = nullptr;
118 : Enum* PluginAPI::chordLineTypeEnum = nullptr;
119 : Enum* PluginAPI::slurStyleTypeEnum = nullptr;
120 : Enum* PluginAPI::tremoloTypeEnum = nullptr;
121 : Enum* PluginAPI::tremoloChordTypeEnum = nullptr;
122 : Enum* PluginAPI::bracketTypeEnum = nullptr;
123 : Enum* PluginAPI::jumpTypeEnum = nullptr;
124 : Enum* PluginAPI::markerTypeEnum = nullptr;
125 : Enum* PluginAPI::measureNumberModeEnum = nullptr;
126 : Enum* PluginAPI::staffGroupEnum = nullptr;
127 : Enum* PluginAPI::ottavaTypeEnum = nullptr;
128 : Enum* PluginAPI::hairpinTypeEnum = nullptr;
129 : Enum* PluginAPI::trillTypeEnum = nullptr;
130 : Enum* PluginAPI::vibratoTypeEnum = nullptr;
131 : Enum* PluginAPI::articulationTextTypeEnum = nullptr;
132 : Enum* PluginAPI::lyricsDashSystemStartEnum = nullptr;
133 : Enum* PluginAPI::noteLineEndPlacementEnum = nullptr;
134 : Enum* PluginAPI::spannerSegmentTypeEnum = nullptr;
135 : Enum* PluginAPI::tiePlacementEnum = nullptr;
136 : Enum* PluginAPI::tieDotsPlacementEnum = nullptr;
137 : Enum* PluginAPI::timeSigTypeEnum = nullptr;
138 : Enum* PluginAPI::timeSigPlacementEnum = nullptr;
139 : Enum* PluginAPI::timeSigStyleEnum = nullptr;
140 : Enum* PluginAPI::timeSigVSMarginEnum = nullptr;
141 : Enum* PluginAPI::noteSpellingTypeEnum = nullptr;
142 : Enum* PluginAPI::keyEnum = nullptr;
143 : Enum* PluginAPI::updateModeEnum = nullptr;
144 : Enum* PluginAPI::layoutFlagEnum = nullptr;
145 : Enum* PluginAPI::layoutModeEnum = nullptr;
146 : Enum* PluginAPI::tappingHandEnum = nullptr;
147 : Enum* PluginAPI::lHTappingSymbolEnum = nullptr;
148 : Enum* PluginAPI::rHTappingSymbolEnum = nullptr;
149 : Enum* PluginAPI::lHTappingShowItemsEnum = nullptr;
150 : Enum* PluginAPI::parenthesesModeEnum = nullptr;
151 : Enum* PluginAPI::repeatPlayCountPresetEnum = nullptr;
152 : Enum* PluginAPI::measureNumberPlacementEnum = nullptr;
153 : Enum* PluginAPI::symIdEnum = nullptr;
154 : Enum* PluginAPI::cursorEnum = nullptr;
155 :
156 : //---------------------------------------------------------
157 : // PluginAPI::registerQmlTypes
158 : //---------------------------------------------------------
159 :
160 0 : void PluginAPI::registerQmlTypes()
161 : {
162 : static bool qmlTypesRegistered = false;
163 0 : if (qmlTypesRegistered) {
164 0 : return;
165 : }
166 :
167 0 : if (-1 == qmlRegisterType<PluginAPI>("MuseScore", 3, 0, "MuseScore")) {
168 0 : LOGW("qmlRegisterType failed: MuseScore");
169 : }
170 :
171 0 : qmlRegisterUncreatableType<Enum>("MuseScore", 3, 0, "MuseScoreEnum", "Cannot create an enumeration");
172 :
173 : //qmlRegisterType<ScoreView>("MuseScore", 3, 0, "ScoreView");
174 :
175 0 : qmlRegisterType<Cursor>("MuseScore", 3, 0, "Cursor");
176 0 : qmlRegisterAnonymousType<ScoreElement>("MuseScore", 3);
177 0 : qmlRegisterAnonymousType<Score>("MuseScore", 3);
178 0 : qmlRegisterAnonymousType<EngravingItem>("MuseScore", 3);
179 0 : qmlRegisterAnonymousType<Chord>("MuseScore", 3);
180 0 : qmlRegisterAnonymousType<Note>("MuseScore", 3);
181 0 : qmlRegisterAnonymousType<Tuplet>("MuseScore", 3);
182 0 : qmlRegisterAnonymousType<DurationElement>("MuseScore", 3);
183 0 : qmlRegisterAnonymousType<Segment>("MuseScore", 3);
184 0 : qmlRegisterAnonymousType<Measure>("MuseScore", 3);
185 0 : qmlRegisterAnonymousType<Part>("MuseScore", 3);
186 0 : qmlRegisterAnonymousType<Staff>("MuseScore", 3);
187 0 : qmlRegisterAnonymousType<Instrument>("MuseScore", 3);
188 0 : qmlRegisterAnonymousType<Channel>("MuseScore", 3);
189 0 : qmlRegisterAnonymousType<StringData>("MuseScore", 3);
190 0 : qmlRegisterAnonymousType<Excerpt>("MuseScore", 3);
191 0 : qmlRegisterAnonymousType<Selection>("MuseScore", 3);
192 0 : qmlRegisterAnonymousType<Tie>("MuseScore", 3);
193 0 : qmlRegisterAnonymousType<Harmony>("MuseScore", 3);
194 0 : qmlRegisterAnonymousType<FretDiagram>("MuseScore", 3);
195 0 : qmlRegisterAnonymousType<Drumset>("MuseScore", 3);
196 0 : qmlRegisterAnonymousType<MeasureBase>("MuseScore", 3);
197 0 : qmlRegisterAnonymousType<System>("MuseScore", 3);
198 0 : qmlRegisterAnonymousType<Spanner>("MuseScore", 3);
199 0 : qmlRegisterAnonymousType<SpannerSegment>("MuseScore", 3);
200 0 : qmlRegisterAnonymousType<Ornament>("MuseScore", 3);
201 0 : qmlRegisterType<PlayEvent>("MuseScore", 3, 0, "PlayEvent");
202 :
203 0 : qmlRegisterAnonymousType<Fraction>("MuseScore", 3);
204 0 : qRegisterMetaType<Fraction*>("Fraction*");
205 0 : qmlRegisterAnonymousType<IntervalWrapper>("MuseScore", 3);
206 0 : qRegisterMetaType<IntervalWrapper*>("IntervalWrapper*");
207 0 : qmlRegisterAnonymousType<OrnamentIntervalWrapper>("MuseScore", 3);
208 0 : qRegisterMetaType<OrnamentIntervalWrapper*>("OrnamentIntervalWrapper*");
209 :
210 0 : qmlRegisterType<MsProcess>("MuseScore", 3, 0, "QProcess");
211 0 : qmlRegisterType<FileIO, 1>("FileIO", 3, 0, "FileIO");
212 :
213 0 : qmlTypesRegistered = true;
214 : }
215 :
216 0 : void PluginAPI::setup(QQmlEngine* e)
217 : {
218 : // Sync PluginAPI and EngravingApiV1
219 :
220 0 : QJSValue apiVal = e->globalObject().property("api");
221 0 : if (apiVal.isNull()) {
222 0 : LOGE() << "not found api object";
223 0 : return;
224 : }
225 :
226 0 : QJSValue engravingApiVal = apiVal.property("engraving");
227 0 : QObject* engravingApiObj = engravingApiVal.toQObject();
228 0 : if (!engravingApiObj) {
229 0 : LOGE() << "not found api.engraving object";
230 0 : return;
231 : }
232 :
233 0 : EngravingApiV1* engravingApi = dynamic_cast<EngravingApiV1*>(engravingApiObj);
234 0 : if (!engravingApi) {
235 0 : LOGE() << "api.engraving object not EngravingApiV1";
236 0 : return;
237 : }
238 :
239 0 : engravingApi->setApi(this);
240 0 : m_engine = engravingApi->engine();
241 0 : }
242 :
243 0 : PluginAPI::PluginAPI(QQuickItem* parent)
244 0 : : QQuickItem(parent), muse::Contextable(muse::iocCtxForQmlObject(this))
245 : {
246 0 : setRequiresScore(true); // by default plugins require a score to work
247 0 : }
248 :
249 0 : PluginAPI::PluginAPI(const muse::modularity::ContextPtr& ctx)
250 0 : : muse::Contextable(ctx)
251 : {
252 0 : setRequiresScore(true); // by default plugins require a score to work
253 0 : }
254 :
255 0 : apiv1::Score* PluginAPI::curScore() const
256 : {
257 0 : if (currentScore()) {
258 0 : return wrap<apiv1::Score>(currentScore(), Ownership::SCORE);
259 : }
260 :
261 0 : return nullptr;
262 : }
263 :
264 0 : QQmlListProperty<apiv1::Score> PluginAPI::scores()
265 : {
266 0 : NOT_IMPLEMENTED;
267 :
268 0 : static std::vector<mu::engraving::Score*> scores;
269 :
270 0 : return wrapContainerProperty<Score>(this, scores);
271 : }
272 :
273 : //---------------------------------------------------------
274 : // writeScore
275 : /// Writes a score to a file.
276 : /// \param s The score which should be saved.
277 : /// \param name Path where to save the score, with or
278 : /// without the filename extension (the extension is
279 : /// determined by \p ext parameter).
280 : /// \param ext Filename extension \b without the dot,
281 : /// e.g. \p "mscz" or \p "pdf". Determines the file
282 : /// format to be used.
283 : //---------------------------------------------------------
284 :
285 0 : bool PluginAPI::writeScore(Score* s, const QString& name, const QString& ext)
286 : {
287 0 : if (!s || !s->score()) {
288 0 : LOGW() << "No score provided";
289 0 : return false;
290 : }
291 :
292 0 : if (s->score() != currentScore()) {
293 0 : LOGW() << "Only writing the selected score is currently supported";
294 0 : return false;
295 : }
296 :
297 0 : return helper()->writeScore(name, ext);
298 : }
299 :
300 : //---------------------------------------------------------
301 : // readScore
302 : /// Reads the score from a file and opens it in a new tab
303 : /// \param name Path to the file to be opened.
304 : /// \param noninteractive Can be used to avoid a "save
305 : /// changes" dialog on closing a score that is either
306 : /// imported or was created with an older version of
307 : /// MuseScore.
308 : //---------------------------------------------------------
309 :
310 0 : apiv1::Score* PluginAPI::readScore(const QString& name, bool noninteractive)
311 : {
312 0 : const bool hadScoreOpened = currentScore();
313 :
314 0 : if (hadScoreOpened) {
315 0 : LOGW() << "Will open a score in a new window";
316 : }
317 :
318 0 : if (noninteractive) {
319 0 : LOGW() << "Noninteractive flag is not yet implemented";
320 0 : return nullptr;
321 : }
322 :
323 0 : mu::engraving::Score* score = helper()->readScore(name);
324 0 : if (score) {
325 0 : return wrap<apiv1::Score>(score, Ownership::SCORE);
326 : }
327 0 : return nullptr;
328 : }
329 :
330 : //---------------------------------------------------------
331 : // closeScore
332 : //---------------------------------------------------------
333 :
334 0 : void PluginAPI::closeScore()
335 : {
336 0 : return closeScore(curScore());
337 : }
338 :
339 0 : void PluginAPI::closeScore(apiv1::Score* score)
340 : {
341 0 : if (!score || !score->score()) {
342 0 : LOGW() << "No score provided";
343 0 : return;
344 : }
345 :
346 0 : if (score->score() != currentScore()) {
347 0 : LOGW() << "Only closing the selected score is currently supported";
348 0 : return;
349 : }
350 :
351 0 : helper()->closeScore();
352 : }
353 :
354 : //---------------------------------------------------------
355 : // newElement
356 : /// Creates a new element with the given type. The
357 : /// element can be then added to a score via Cursor::add.
358 : /// \param elementType EngravingItem type, should be the value
359 : /// from PluginAPI::PluginAPI::EngravingItem enumeration.
360 : //---------------------------------------------------------
361 :
362 0 : apiv1::EngravingItem* PluginAPI::newElement(int elementType)
363 : {
364 0 : mu::engraving::Score* score = currentScore();
365 :
366 0 : if (!score) {
367 0 : return nullptr;
368 : }
369 :
370 0 : if (elementType <= int(ElementType::INVALID) || elementType >= int(ElementType::ROOT_ITEM)) {
371 0 : LOGW("PluginAPI::newElement: Wrong type ID: %d", elementType);
372 0 : return nullptr;
373 : }
374 :
375 0 : const ElementType type = ElementType(elementType);
376 0 : mu::engraving::EngravingItem* e = Factory::createItem(type, score->dummy());
377 0 : return wrap(e, Ownership::PLUGIN);
378 : }
379 :
380 : //---------------------------------------------------------
381 : // removeElement
382 : /// Disposes of an EngravingItem and its children.
383 : /// \param EngravingItem type.
384 : /// \since MuseScore 3.3
385 : //---------------------------------------------------------
386 :
387 0 : void PluginAPI::removeElement(apiv1::EngravingItem* wrapped)
388 : {
389 0 : mu::engraving::Score* score = wrapped->element()->score();
390 0 : score->deleteItem(wrapped->element());
391 0 : }
392 :
393 : //---------------------------------------------------------
394 : // newScore
395 : //---------------------------------------------------------
396 :
397 0 : apiv1::Score* PluginAPI::newScore(const QString& /*name*/, const QString& part, int measures)
398 : {
399 0 : if (currentScore()) {
400 0 : currentScore()->endCmd();
401 : }
402 :
403 0 : MasterScore* score = mu::engraving::compat::ScoreAccess::createMasterScoreWithDefaultStyle(iocContext());
404 :
405 : // TODO: Set path/filename
406 0 : NOT_IMPLEMENTED << "setting path/filename";
407 :
408 0 : score->appendPart(Score::instrTemplateFromName(part));
409 0 : score->appendMeasures(measures);
410 0 : score->doLayout();
411 :
412 : // TODO: Open score
413 0 : NOT_IMPLEMENTED << "opening the newly created score";
414 :
415 0 : qApp->processEvents();
416 0 : Q_ASSERT(currentScore() == score);
417 0 : score->startCmd(TranslatableString("undoableAction", "New score"));
418 0 : return wrap<Score>(score, Ownership::SCORE);
419 : }
420 :
421 0 : void PluginAPI::cmd(const QString& s)
422 : {
423 : static const QMap<QString, muse::rcommand::Command> COMPAT_CMD_MAP = {
424 : { "escape", notation::CANCEL_COMMAND },
425 : { "cut", notation::CUT_COMMAND },
426 : { "copy", notation::COPY_COMMAND },
427 : { "paste", notation::PASTE_COMMAND },
428 : { "paste-half", notation::PASTE_HALF_COMMAND },
429 : { "paste-double", notation::PASTE_DOUBLE_COMMAND },
430 : { "select-all", notation::SELECT_ALL_COMMAND },
431 : { "delete", notation::DELETE_COMMAND },
432 : { "next-chord", notation::MOVE_RIGHT_COMMAND },
433 : { "prev-chord", notation::MOVE_LEFT_COMMAND },
434 : { "prev-measure", notation::MOVE_LEFT_QUICKLY_COMMAND }
435 0 : };
436 :
437 0 : commandDispatcher()->dispatch(COMPAT_CMD_MAP.value(s, muse::rcommand::Command(s.toStdString())));
438 0 : }
439 :
440 0 : void PluginAPI::openLog(const QString&)
441 : {
442 0 : DEPRECATED;
443 0 : }
444 :
445 0 : void PluginAPI::closeLog()
446 : {
447 0 : DEPRECATED;
448 0 : }
449 :
450 0 : void PluginAPI::log(const QString& txt)
451 : {
452 0 : LOGD() << txt;
453 0 : }
454 :
455 0 : void PluginAPI::logn(const QString& txt)
456 : {
457 0 : LOGD() << txt;
458 0 : }
459 :
460 0 : void PluginAPI::log2(const QString& txt, const QString& txt2)
461 : {
462 0 : LOGD() << txt << txt2;
463 0 : }
464 :
465 : //---------------------------------------------------------
466 : // newQProcess
467 : /// Not enabled currently (so excluded from plugin docs)
468 : //---------------------------------------------------------
469 :
470 0 : MsProcess* PluginAPI::newQProcess()
471 : {
472 0 : NOT_IMPLEMENTED;
473 0 : return nullptr;
474 : }
475 :
476 : //---------------------------------------------------------
477 : // PluginAPI::fraction
478 : /// Creates a new fraction with the given numerator and
479 : /// denominator
480 : //---------------------------------------------------------
481 :
482 0 : apiv1::Fraction* PluginAPI::fraction(int num, int den) const
483 : {
484 0 : return wrap(mu::engraving::Fraction(num, den));
485 : }
486 :
487 : //---------------------------------------------------------
488 : // PluginAPI::fractionFromTicks
489 : /// Converts an integer tick value to an equivalent fraction.
490 : /// \since MuseScore 4.6
491 : //---------------------------------------------------------
492 :
493 0 : apiv1::Fraction* PluginAPI::fractionFromTicks(int ticks) const
494 : {
495 0 : return wrap(mu::engraving::Fraction::fromTicks(ticks));
496 : }
497 :
498 0 : void PluginAPI::quit()
499 : {
500 0 : emit closeRequested();
501 0 : m_closeRequested.notify();
502 0 : }
503 :
504 0 : mu::engraving::Score* PluginAPI::currentScore() const
505 : {
506 0 : if (notation::INotationPtr notation = context()->currentNotation()) {
507 0 : return notation->elements()->msScore();
508 0 : }
509 :
510 0 : return nullptr;
511 : }
512 :
513 0 : QString PluginAPI::pluginType() const
514 : {
515 0 : return m_pluginType;
516 : }
517 :
518 0 : void PluginAPI::setPluginType(const QString& newPluginType)
519 : {
520 0 : m_pluginType = newPluginType;
521 0 : }
522 :
523 0 : QString PluginAPI::menuPath() const
524 : {
525 0 : return QString();
526 : }
527 :
528 0 : void PluginAPI::setMenuPath(const QString&)
529 : {
530 0 : DEPRECATED;
531 0 : }
532 :
533 0 : QString PluginAPI::title() const
534 : {
535 0 : return m_title;
536 : }
537 :
538 0 : void PluginAPI::setTitle(const QString& newTitle)
539 : {
540 0 : m_title = newTitle;
541 0 : }
542 :
543 0 : QString PluginAPI::version() const
544 : {
545 0 : return m_version;
546 : }
547 :
548 0 : void PluginAPI::setVersion(const QString& newVersion)
549 : {
550 0 : m_version = newVersion;
551 0 : }
552 :
553 0 : QString PluginAPI::description() const
554 : {
555 0 : return m_description;
556 : }
557 :
558 0 : void PluginAPI::setDescription(const QString& newDescription)
559 : {
560 0 : m_description = newDescription;
561 0 : }
562 :
563 0 : QString PluginAPI::dockArea() const
564 : {
565 0 : return QString();
566 : }
567 :
568 0 : void PluginAPI::setDockArea(const QString&)
569 : {
570 0 : DEPRECATED;
571 0 : }
572 :
573 0 : bool PluginAPI::requiresScore() const
574 : {
575 0 : return m_requiresScore;
576 : }
577 :
578 0 : void PluginAPI::setRequiresScore(bool newRequiresScore)
579 : {
580 0 : m_requiresScore = newRequiresScore;
581 0 : }
582 :
583 0 : QString PluginAPI::thumbnailName() const
584 : {
585 0 : return m_thumbnailName;
586 : }
587 :
588 0 : void PluginAPI::setThumbnailName(const QString& newThumbnailName)
589 : {
590 0 : m_thumbnailName = newThumbnailName;
591 0 : }
592 :
593 0 : QString PluginAPI::categoryCode() const
594 : {
595 0 : return m_categoryCode;
596 : }
597 :
598 0 : void PluginAPI::setCategoryCode(const QString& newCategoryCode)
599 : {
600 0 : m_categoryCode = newCategoryCode;
601 0 : }
602 :
603 0 : int PluginAPI::division() const
604 : {
605 0 : return engraving::Constants::DIVISION;
606 : }
607 :
608 0 : int PluginAPI::mscoreVersion() const
609 : {
610 0 : return mscoreMajorVersion() * 10000 + mscoreMinorVersion() * 100 + mscoreUpdateVersion();
611 : }
612 :
613 0 : int PluginAPI::mscoreMajorVersion() const
614 : {
615 0 : return application()->version().major();
616 : }
617 :
618 0 : int PluginAPI::mscoreMinorVersion() const
619 : {
620 0 : return application()->version().minor();
621 : }
622 :
623 0 : int PluginAPI::mscoreUpdateVersion() const
624 : {
625 0 : return application()->version().patch();
626 : }
627 :
628 0 : qreal PluginAPI::mscoreDPI() const
629 : {
630 0 : return engraving::DPI;
631 : }
632 :
633 0 : OrnamentIntervalWrapper* PluginAPI::defaultOrnamentInterval() const
634 : {
635 0 : return wrap(mu::engraving::DEFAULT_ORNAMENT_INTERVAL);
636 : }
637 :
638 : //---------------------------------------------------------
639 : // PluginAPI::ornamentInterval
640 : /// Creates a new ornament interval with the given step and type
641 : //---------------------------------------------------------
642 :
643 0 : OrnamentIntervalWrapper* PluginAPI::ornamentInterval(int step, int type) const
644 : {
645 0 : return wrap(mu::engraving::OrnamentInterval(mu::engraving::IntervalStep(step), mu::engraving::IntervalType(type)));
646 : }
647 :
648 : //---------------------------------------------------------
649 : // PluginAPI::interval
650 : /// Creates a new interval with the given chromatic and diatonic steps
651 : //---------------------------------------------------------
652 :
653 0 : IntervalWrapper* PluginAPI::interval(int diatonic, int chromatic) const
654 : {
655 0 : return wrap(mu::engraving::Interval(diatonic, chromatic));
656 : }
657 :
658 : //---------------------------------------------------------
659 : // PluginAPI::intervalFromOrnamentInterval
660 : /// Creates a new interval from a given ornament interval
661 : //---------------------------------------------------------
662 :
663 0 : IntervalWrapper* PluginAPI::intervalFromOrnamentInterval(OrnamentIntervalWrapper* o) const
664 : {
665 0 : return wrap(mu::engraving::Interval::fromOrnamentInterval(o->ornamentInterval()));
666 : }
|