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 "templatesrepository.h"
24 :
25 : #include "io/path.h"
26 : #include "translation.h"
27 : #include "log.h"
28 :
29 : #include <QJsonDocument>
30 : #include <QJsonObject>
31 : #include <QJsonArray>
32 :
33 : using namespace muse;
34 : using namespace mu::project;
35 :
36 1 : RetVal<Templates> TemplatesRepository::templates() const
37 : {
38 2 : TRACEFUNC;
39 :
40 1 : Templates templates;
41 :
42 4 : for (const muse::io::path_t& dir : configuration()->availableTemplateDirs()) {
43 3 : templates << readTemplates(dir);
44 1 : }
45 :
46 2 : return RetVal<Templates>::make_ok(templates);
47 1 : }
48 :
49 3 : Templates TemplatesRepository::readTemplates(const muse::io::path_t& dirPath) const
50 : {
51 4 : TRACEFUNC;
52 :
53 3 : muse::io::path_t categoriesJsonPath = configuration()->templateCategoriesJsonPath(dirPath);
54 :
55 3 : if (!fileSystem()->exists(categoriesJsonPath)) {
56 2 : RetVal<io::paths_t> files = fileSystem()->scanFiles(dirPath, { "*.mscz", "*.mscx" });
57 1 : if (!files.ret) {
58 0 : LOGE() << files.ret.toString();
59 0 : return Templates();
60 : }
61 :
62 1 : return readTemplates(files.val, muse::qtrc("project", "My templates"), true /*isCustom*/);
63 1 : }
64 :
65 2 : RetVal<ByteArray> categoriesJson = fileSystem()->readFile(categoriesJsonPath);
66 2 : if (!categoriesJson.ret) {
67 0 : LOGE() << categoriesJson.ret.toString();
68 0 : return Templates();
69 : }
70 :
71 2 : QJsonDocument document = QJsonDocument::fromJson(categoriesJson.val.toQByteArrayNoCopy());
72 2 : QVariantList categoryObjList = document.array().toVariantList();
73 :
74 2 : Templates templates;
75 :
76 5 : for (const QVariant& obj : categoryObjList) {
77 3 : QVariantMap map = obj.toMap();
78 3 : QString categoryTitle = muse::qtrc("project", map["title"].toString().toUtf8().data());
79 3 : QStringList files = map["files"].toStringList();
80 :
81 3 : io::paths_t paths;
82 7 : for (const QString& path : files) {
83 4 : paths.push_back(path);
84 : }
85 :
86 3 : templates << readTemplates(paths, categoryTitle, false /*isCustom*/, dirPath);
87 3 : }
88 :
89 2 : return templates;
90 3 : }
91 :
92 4 : Templates TemplatesRepository::readTemplates(const io::paths_t& files, const QString& category, bool isCustom,
93 : const muse::io::path_t& dirPath) const
94 : {
95 5 : TRACEFUNC;
96 :
97 4 : Templates templates;
98 :
99 10 : for (const muse::io::path_t& file : files) {
100 6 : muse::io::path_t path = dirPath.empty() ? file : dirPath + "/" + file;
101 6 : RetVal<ProjectMeta> meta = mscReader()->readMeta(path);
102 6 : if (!meta.ret) {
103 0 : LOGE() << QString("failed read template %1: %2")
104 0 : .arg(path.toQString())
105 0 : .arg(QString::fromStdString(meta.ret.toString()));
106 0 : continue;
107 : }
108 :
109 6 : Template templ;
110 6 : templ.categoryTitle = category;
111 6 : templ.meta = std::move(meta.val);
112 6 : templ.isCustom = isCustom;
113 :
114 6 : templates << templ;
115 6 : }
116 :
117 4 : return templates;
118 4 : }
|