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 : #include "interactivetestsmodel.h"
23 :
24 : #include <QTimer>
25 : #include <QAccessible>
26 :
27 : #include "async/async.h"
28 :
29 : #include "global/progress.h"
30 :
31 : #include "log.h"
32 :
33 : using namespace muse::interactive;
34 :
35 : struct ProgressData
36 : {
37 : muse::Progress progress;
38 : QTimer timer;
39 : int total = 10;
40 : int current = 0;
41 : };
42 :
43 0 : InteractiveTestsModel::InteractiveTestsModel(QObject* parent)
44 0 : : QObject(parent), Contextable(muse::iocCtxForQmlObject(this))
45 : {
46 0 : }
47 :
48 0 : void InteractiveTestsModel::init()
49 : {
50 0 : ValCh<Uri> uri = interactive()->currentUri();
51 0 : setCurrentUri(uri.val);
52 0 : uri.ch.onReceive(this, [this](const Uri& uri) {
53 0 : setCurrentUri(uri);
54 0 : });
55 0 : }
56 :
57 0 : void InteractiveTestsModel::selectOpeningFile()
58 : {
59 0 : io::path_t path = interactive()->selectOpeningFileSync("Sample select file", qApp->applicationDirPath(),
60 0 : { "Text files (*.txt)", "Cmake files (*.cmake)" });
61 0 : LOGI() << "path: " << path;
62 0 : }
63 :
64 0 : void InteractiveTestsModel::selectSavingFile()
65 : {
66 0 : io::path_t path = interactive()->selectSavingFileSync("Sample select file", qApp->applicationDirPath(),
67 0 : { "Text files (*.txt)", "Cmake files (*.cmake)" });
68 0 : LOGI() << "path: " << path;
69 0 : }
70 :
71 0 : void InteractiveTestsModel::selectDirectory()
72 : {
73 0 : io::path_t path = interactive()->selectDirectory("Sample select file", qApp->applicationDirPath());
74 0 : LOGI() << "path: " << path;
75 0 : }
76 :
77 0 : void InteractiveTestsModel::showProgress()
78 : {
79 0 : ProgressData* pd = new ProgressData();
80 0 : pd->timer.setInterval(1000);
81 0 : connect(&pd->timer, &QTimer::timeout, [pd]() {
82 0 : pd->current++;
83 0 : pd->progress.progress(pd->current, pd->total, "bla-bla");
84 :
85 0 : if (pd->current >= pd->total) {
86 0 : pd->timer.stop();
87 0 : pd->progress.finish(ProgressResult::make_ok(Val()));
88 :
89 0 : async::Async::call(nullptr, [pd]() {
90 0 : delete pd;
91 0 : });
92 : }
93 0 : });
94 :
95 0 : interactive()->showProgress("Progress sample", pd->progress);
96 :
97 0 : pd->timer.start();
98 0 : pd->progress.start();
99 0 : }
100 :
101 0 : void InteractiveTestsModel::openSampleDialogSync()
102 : {
103 0 : LOGI() << "cpp: before open";
104 0 : RetVal<Val> rv = interactive()->openSync("muse://devtools/interactive/sample?color=#474747");
105 0 : LOGI() << "cpp: after open ret: " << rv.ret.toString() << ", val: " << rv.val.toString();
106 0 : }
107 :
108 0 : void InteractiveTestsModel::openSampleDialogAsync()
109 : {
110 0 : LOGI() << "cpp: before open ";
111 0 : interactive()->open("muse://devtools/interactive/sample?color=#D24373");
112 0 : LOGI() << "cpp: after open";
113 0 : }
114 :
115 0 : void InteractiveTestsModel::closeSampleDialog()
116 : {
117 0 : LOGI() << "cpp: before close ";
118 0 : interactive()->close(Uri("muse://devtools/interactive/sample"));
119 0 : LOGI() << "cpp: after close";
120 0 : }
121 :
122 0 : void InteractiveTestsModel::openSampleDialogAsyncWithPromise()
123 : {
124 0 : auto promise = interactive()->open("muse://devtools/interactive/sample?color=#D24358");
125 0 : promise.onResolve(this, [](const Val& val) {
126 0 : LOGI() << "success val: " << val.toString();
127 0 : }).onReject(this, [](int code, const std::string& err) {
128 0 : LOGE() << "error or cancel code: " << code << ", err: " << err;
129 0 : });
130 0 : }
131 :
132 0 : void InteractiveTestsModel::openWidgetDialog()
133 : {
134 0 : LOGI() << "cpp: before open ";
135 0 : RetVal<Val> rv = interactive()->openSync("muse://devtools/interactive/testdialog?title='And from its properties'");
136 0 : LOGI() << "cpp: after open ret: " << rv.ret.toString() << ", val: " << rv.val.toString();
137 0 : }
138 :
139 0 : void InteractiveTestsModel::openWidgetDialogAsync()
140 : {
141 0 : LOGI() << "cpp: before open ";
142 0 : auto promise = interactive()->open("muse://devtools/interactive/testdialog?title='And from its properties'");
143 0 : LOGI() << "cpp: after open";
144 0 : promise.onResolve(this, [](const Val& val) {
145 0 : LOGI() << "success val: " << val.toString();
146 0 : }).onReject(this, [](int code, const std::string& err) {
147 0 : LOGE() << "error or cancel code: " << code << ", err: " << err;
148 0 : });
149 0 : }
150 :
151 0 : void InteractiveTestsModel::closeWidgetDialog()
152 : {
153 0 : LOGI() << "cpp: before close ";
154 0 : interactive()->close(Uri("muse://devtools/interactive/testdialog"));
155 0 : LOGI() << "cpp: after close";
156 0 : }
157 :
158 0 : void InteractiveTestsModel::setCurrentUri(const Uri& uri)
159 : {
160 0 : m_currentUri = QString::fromStdString(uri.toString());
161 0 : emit currentUriChanged(m_currentUri);
162 0 : }
163 :
164 0 : QString InteractiveTestsModel::currentUri() const
165 : {
166 0 : return m_currentUri;
167 : }
168 :
169 0 : void InteractiveTestsModel::question()
170 : {
171 0 : IInteractive::Result result = interactive()->questionSync(
172 : "Do you really want to delete the 'xxx' workspace?", "",
173 0 : { interactive()->buttonData(IInteractive::Button::No),
174 0 : interactive()->buttonData(IInteractive::Button::Yes) }, 0,
175 : IInteractive::Option::WithIcon);
176 :
177 0 : if (result.standardButton() == IInteractive::Button::Yes) {
178 0 : LOGI() << "Yes!!";
179 : } else {
180 0 : LOGI() << "No!!";
181 : }
182 0 : }
183 :
184 0 : void InteractiveTestsModel::questionByUri()
185 : {
186 0 : auto promise = interactive()->question(
187 : "Do you really want to delete the 'xxx' workspace?", "",
188 : { IInteractive::Button::No, IInteractive::Button::Yes }, IInteractive::Button::NoButton,
189 0 : IInteractive::Option::WithIcon);
190 :
191 0 : promise.onResolve(this, [](const IInteractive::Result& res) {
192 0 : if (res.standardButton() == IInteractive::Button::Yes) {
193 0 : LOGI() << "Yes!!";
194 : } else {
195 0 : LOGI() << "No!!";
196 : }
197 0 : }).onReject(this, [](int code, const std::string& err) {
198 0 : LOGE() << code << err;
199 0 : });
200 0 : }
201 :
202 0 : void InteractiveTestsModel::customQuestion()
203 : {
204 0 : int maybeBtn = int(IInteractive::Button::CustomButton) + 1;
205 0 : IInteractive::Result result = interactive()->questionSync("Test", "It works?", {
206 0 : IInteractive::ButtonData(maybeBtn, "Maybe"),
207 0 : interactive()->buttonData(IInteractive::Button::No)
208 : });
209 :
210 0 : if (result.button() == maybeBtn) {
211 0 : LOGI() << "Maybe!!";
212 : } else {
213 0 : LOGE() << "No!!";
214 : }
215 0 : }
216 :
217 0 : void InteractiveTestsModel::information()
218 : {
219 0 : auto result = interactive()->info("Tuplet cannot cross barlines",
220 0 : std::string(), {}, 0,
221 : IInteractive::Option::WithIcon
222 0 : | IInteractive::Option::WithDontShowAgainCheckBox)
223 0 : .onResolve(this, [this](const IInteractive::Result& res) {
224 0 : LOGD() << interactive()->buttonData(res.standardButton()).text;
225 0 : });
226 0 : }
227 :
228 0 : void InteractiveTestsModel::warning()
229 : {
230 0 : IInteractive::Result result = interactive()->warningSync("Do you want to save changes to the score “Untitled” before closing?",
231 : "Your changes will be lost if you don’t save them.",
232 0 : { interactive()->buttonData(IInteractive::Button::DontSave),
233 0 : interactive()->buttonData(IInteractive::Button::Save),
234 0 : interactive()->buttonData(IInteractive::Button::Cancel) });
235 :
236 0 : if (result.standardButton() == IInteractive::Button::DontSave) {
237 0 : LOGI() << "Don’t save!!";
238 0 : } else if (result.standardButton() == IInteractive::Button::Save) {
239 0 : LOGE() << "Save!!";
240 : } else {
241 0 : LOGE() << "Cancel!!";
242 : }
243 0 : }
244 :
245 0 : void InteractiveTestsModel::critical()
246 : {
247 0 : IInteractive::Result result = interactive()->errorSync("Cannot read file C:/Users/Username/Desktop/Composition.mscz",
248 0 : std::string("An error has occurred when trying to open this file"));
249 0 : LOGD() << interactive()->buttonData(result.standardButton()).text;
250 0 : }
251 :
252 0 : void InteractiveTestsModel::criticalWithDetailedText()
253 : {
254 0 : IInteractive::Text text;
255 0 : text.text = std::string("An error has occurred when trying to open this file");
256 0 : text.detailedText = std::string("Permission denied");
257 0 : IInteractive::Result result = interactive()->errorSync("Cannot read file C:/Users/Username/Desktop/Composition.mscz", text);
258 0 : LOGD() << interactive()->buttonData(result.standardButton()).text;
259 0 : }
260 :
261 0 : void InteractiveTestsModel::require()
262 : {
263 0 : RetVal<Val> rv = interactive()->openSync("muse://devtools/interactive/sample?title='Test'");
264 0 : if (rv.ret) {
265 0 : LOGI() << "received: " << rv.val.toString();
266 0 : } else if (check_ret(rv.ret, Ret::Code::Cancel)) {
267 0 : LOGI() << "was cancelled";
268 : } else {
269 0 : LOGE() << "some error: " << rv.ret.code();
270 : }
271 0 : }
|