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 : #include "paletteworkspacesetup.h"
23 :
24 : #include "io/buffer.h"
25 :
26 : #include "palettecreator.h"
27 : #include "../palettetypes.h"
28 :
29 : #include "engraving/dom/masterscore.h"
30 : #include "engraving/rw/xmlreader.h"
31 : #include "engraving/rw/xmlwriter.h"
32 :
33 : #include "log.h"
34 :
35 : using namespace mu;
36 : using namespace mu::palette;
37 : using namespace muse;
38 : using namespace muse::io;
39 : using namespace muse::workspace;
40 :
41 : static const AsciiStringView PALETTE_XML_TAG("PaletteBox");
42 :
43 0 : PaletteTreePtr PaletteWorkspaceSetup::readPalette(const ByteArray& data, const muse::modularity::ContextPtr& iocCtx)
44 : {
45 0 : ByteArray ba = ByteArray::fromRawData(data.constData(), data.size());
46 0 : auto buf = Buffer::opened(IODevice::ReadOnly, &ba);
47 0 : mu::engraving::XmlReader reader(&buf);
48 :
49 0 : while (!reader.atEnd()) {
50 0 : reader.readNextStartElement();
51 :
52 0 : if (reader.name() == PALETTE_XML_TAG) {
53 0 : int mscVersion = 0;
54 0 : if (reader.hasAttribute("version")) {
55 0 : const String version = reader.attribute("version");
56 0 : const StringList sl = version.split(u'.');
57 0 : mscVersion = sl.size() == 2 ? sl[0].toInt() * 100 + sl[1].toInt() : 0;
58 0 : } else {
59 : // Versioning workspace palette files started in 4.7. All unversioned files should be treated like 4.6 files
60 0 : mscVersion = 460;
61 : }
62 0 : paletteScoreProvider()->paletteScore()->setMscVersion(mscVersion);
63 :
64 0 : PaletteTreePtr tree = std::make_shared<PaletteTree>();
65 0 : tree->read(reader, false, iocCtx);
66 0 : return tree;
67 0 : }
68 : }
69 :
70 0 : return nullptr;
71 0 : }
72 :
73 0 : void PaletteWorkspaceSetup::writePalette(const PaletteTreePtr& tree, QByteArray& data)
74 : {
75 0 : auto buf = Buffer::opened(IODevice::WriteOnly);
76 0 : mu::engraving::XmlWriter writer(&buf);
77 0 : tree->write(writer, false);
78 0 : writer.flush();
79 0 : data = buf.data().toQByteArray();
80 0 : }
81 :
82 0 : void PaletteWorkspaceSetup::setup()
83 : {
84 0 : if (!workspacesDataProvider()) {
85 0 : return;
86 : }
87 :
88 0 : paletteProvider()->setDefaultPaletteTree(PaletteCreator(iocContext()).newDefaultPaletteTree());
89 :
90 0 : auto saveData = [this]() {
91 0 : PaletteTreePtr tree = paletteProvider()->userPaletteTree();
92 :
93 0 : QByteArray newData;
94 0 : writePalette(tree, newData);
95 :
96 0 : workspacesDataProvider()->setRawData(WS_Palettes, newData);
97 0 : };
98 :
99 0 : paletteProvider()->userPaletteTreeChanged().onNotify(this, saveData);
100 :
101 0 : auto loadData = [this, saveData]() {
102 0 : RetVal<QByteArray> data = workspacesDataProvider()->rawData(WS_Palettes);
103 0 : PaletteTreePtr tree;
104 0 : if (data.ret && !data.val.isEmpty()) {
105 0 : LOGD() << "there is palette data in the workspace, we will use it";
106 0 : ByteArray ba = ByteArray::fromQByteArrayNoCopy(data.val);
107 0 : tree = readPalette(ba, iocContext());
108 0 : } else {
109 0 : LOGD() << "no palette data in workspace, will use default";
110 0 : tree = PaletteCreator(iocContext()).newDefaultPaletteTree();
111 : }
112 0 : paletteProvider()->setUserPaletteTree(tree);
113 :
114 0 : if (paletteScoreProvider()->paletteScore()->mscVersion() < engraving::Constants::MSC_VERSION) {
115 0 : LOGD() << "Workspace file found with palette file version " << paletteScoreProvider()->paletteScore()->mscVersion() <<
116 0 : ". Migrating palette file to " << engraving::Constants::MSC_VERSION;
117 0 : saveData();
118 : }
119 0 : };
120 :
121 0 : workspacesDataProvider()->workspaceChanged().onNotify(this, loadData);
122 :
123 0 : loadData();
124 : }
|