Line data Source code
1 : /*
2 : * SPDX-License-Identifier: GPL-3.0-only
3 : * MuseScore-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 "uiarrangement.h"
24 :
25 : #include <QJsonDocument>
26 : #include <QJsonValue>
27 : #include <QJsonArray>
28 :
29 : #include "uitypes.h"
30 :
31 : #include "muse_framework_config.h"
32 :
33 : #include "log.h"
34 :
35 : using namespace muse::ui;
36 : using namespace muse::workspace;
37 :
38 0 : void UiArrangement::load()
39 : {
40 0 : if (!workspacesDataProvider()) {
41 0 : return;
42 : }
43 :
44 0 : workspacesDataProvider()->workspaceChanged().onNotify(this, [this]() {
45 0 : updateData(WS_UiSettings, m_settings, m_valuesNotifications);
46 0 : updateData(WS_UiStates, m_states, m_statesNotifications);
47 0 : updateData(WS_UiToolConfigs, m_toolconfigs, m_toolconfigsNotifications);
48 0 : });
49 :
50 0 : updateData(WS_UiSettings, m_settings, m_valuesNotifications);
51 0 : updateData(WS_UiStates, m_states, m_statesNotifications);
52 0 : updateData(WS_UiToolConfigs, m_toolconfigs, m_toolconfigsNotifications);
53 : }
54 :
55 0 : void UiArrangement::updateData(DataKey key, QJsonObject& obj, Notifications& notifications) const
56 : {
57 0 : RetVal<QByteArray> data = workspacesDataProvider()->rawData(key);
58 0 : if (!data.ret) {
59 0 : LOGD() << "no data: " << key;
60 0 : obj = QJsonObject();
61 0 : return;
62 : }
63 :
64 0 : QJsonObject oldObj = obj;
65 0 : obj = QJsonDocument::fromJson(data.val).object();
66 :
67 0 : Notifications::Iterator it = notifications.begin();
68 0 : for (; it != notifications.end(); ++it) {
69 0 : const QString& k = it.key();
70 :
71 0 : if (oldObj.value(k) != obj.value(k)) {
72 0 : it.value().notify();
73 : }
74 : }
75 0 : }
76 :
77 0 : void UiArrangement::saveData(DataKey key, const QJsonObject& obj)
78 : {
79 0 : QByteArray data = QJsonDocument(obj).toJson();
80 0 : workspacesDataProvider()->setRawData(key, data);
81 0 : }
82 :
83 0 : QString UiArrangement::value(const QString& key) const
84 : {
85 0 : QJsonValue val = m_settings.value(key);
86 0 : return val.toString();
87 0 : }
88 :
89 0 : void UiArrangement::setValue(const QString& key, const QString& val)
90 : {
91 0 : m_settings[key] = val;
92 0 : saveData(WS_UiSettings, m_settings);
93 0 : if (m_valuesNotifications.contains(key)) {
94 0 : m_valuesNotifications[key].notify();
95 : }
96 0 : }
97 :
98 0 : muse::async::Notification UiArrangement::valueChanged(const QString& key) const
99 : {
100 0 : return m_valuesNotifications[key];
101 : }
102 :
103 0 : QByteArray UiArrangement::state(const QString& key) const
104 : {
105 0 : QJsonValue val = m_states.value(key);
106 0 : QString valStr = val.toString();
107 0 : return valStr.toLocal8Bit();
108 0 : }
109 :
110 0 : void UiArrangement::setState(const QString& key, const QByteArray& data)
111 : {
112 0 : m_states[key] = QString::fromLocal8Bit(data);
113 0 : saveData(WS_UiStates, m_states);
114 0 : if (m_statesNotifications.contains(key)) {
115 0 : m_statesNotifications[key].notify();
116 : }
117 0 : }
118 :
119 0 : muse::async::Notification UiArrangement::stateChanged(const QString& key) const
120 : {
121 0 : return m_statesNotifications[key];
122 : }
123 :
124 0 : ToolConfig UiArrangement::toolConfig(const QString& toolName) const
125 : {
126 0 : TRACEFUNC;
127 :
128 : //! NOTE Maybe we need to cache?
129 :
130 0 : QJsonObject confObj = m_toolconfigs.value(toolName).toObject();
131 0 : QJsonArray itemsArr = confObj.value("items").toArray();
132 :
133 0 : ToolConfig config;
134 :
135 0 : config.items.reserve(itemsArr.size());
136 :
137 0 : bool lastWasSeparator = false;
138 0 : for (const QJsonValue v : itemsArr) {
139 0 : QJsonObject itemObj = v.toObject();
140 :
141 0 : ToolConfig::Item item;
142 0 : item.intent = itemObj.value("action").toString().toStdString();
143 0 : item.show = itemObj.value("show").toInt(1);
144 :
145 0 : if (item.isSeparator() && lastWasSeparator) {
146 0 : continue;
147 : }
148 0 : lastWasSeparator = item.isSeparator();
149 :
150 0 : config.items.push_back(std::move(item));
151 0 : }
152 :
153 0 : return config;
154 0 : }
155 :
156 0 : void UiArrangement::setToolConfig(const QString& toolName, const ToolConfig& config)
157 : {
158 0 : TRACEFUNC;
159 0 : QJsonObject confObj;
160 0 : QJsonArray itemsArr;
161 :
162 0 : for (const ToolConfig::Item& item : config.items) {
163 0 : QJsonObject itemObj;
164 0 : itemObj["action"] = QString::fromStdString(item.intent);
165 0 : itemObj["show"] = item.show ? 1 : 0;
166 :
167 0 : itemsArr.append(itemObj);
168 0 : }
169 :
170 0 : confObj["items"] = itemsArr;
171 :
172 0 : m_toolconfigs[toolName] = confObj;
173 0 : saveData(WS_UiToolConfigs, m_toolconfigs);
174 0 : if (m_toolconfigsNotifications.contains(toolName)) {
175 0 : m_toolconfigsNotifications[toolName].notify();
176 : }
177 0 : }
178 :
179 0 : muse::async::Notification UiArrangement::toolConfigChanged(const QString& toolName) const
180 : {
181 0 : return m_toolconfigsNotifications[toolName];
182 : }
|