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 : #pragma once
24 :
25 : #include "modularity/imoduleinterface.h"
26 : #include "io/path.h"
27 : #include "types/val.h"
28 : #include "types/retval.h"
29 : #include "types/uri.h"
30 : #include "types/flags.h"
31 : #include "types/color.h"
32 : #include "async/promise.h"
33 : #include "progress.h"
34 :
35 : class QWindow;
36 :
37 : namespace muse {
38 : class IInteractive : MODULE_CONTEXT_INTERFACE
39 : {
40 0 : INTERFACE_ID(IInteractive)
41 :
42 : public:
43 307 : virtual ~IInteractive() = default;
44 :
45 : // question
46 : enum class Button {
47 : NoButton,
48 : Ok,
49 : Continue,
50 : RestoreDefaults,
51 : Reset,
52 : Apply,
53 : Help,
54 : Discard,
55 : Cancel,
56 : Close,
57 : Ignore,
58 : Retry,
59 : Abort,
60 : NoToAll,
61 : No,
62 : YesToAll,
63 : Yes,
64 : Open,
65 : DontSave,
66 : SaveAll,
67 : Save,
68 : Next,
69 : Back,
70 : Select,
71 : Clear,
72 : Done,
73 :
74 : CustomButton,
75 : };
76 : using Buttons = std::vector<Button>;
77 :
78 : enum ButtonRole { // Keep updated with ButtonRole in buttonboxmodel.h
79 : AcceptRole,
80 : RejectRole,
81 : DestructiveRole,
82 : ResetRole,
83 : ApplyRole,
84 : RetryRole,
85 : HelpRole,
86 : ContinueRole,
87 : BackRole,
88 : CustomRole
89 : };
90 :
91 : struct ButtonData {
92 : int btn = int(Button::CustomButton);
93 : std::string text;
94 : bool accent = false;
95 : bool leftSide = false;
96 : ButtonRole role = ButtonRole::CustomRole;
97 : int icon = 0; // ui::IconCode::Code, 0 = no icon
98 :
99 32 : ButtonData(int btn, const std::string& text)
100 32 : : btn(btn), text(text) {}
101 91 : ButtonData(Button btn, const std::string& text)
102 91 : : btn(int(btn)), text(text) {}
103 32 : ButtonData(int btn, const std::string& text, bool accent, bool leftSide = false, ButtonRole role = ButtonRole::CustomRole)
104 32 : : btn(btn), text(text), accent(accent), leftSide(leftSide), role(role) {}
105 8 : ButtonData(Button btn, const std::string& text, bool accent, bool leftSide = false, ButtonRole role = ButtonRole::CustomRole)
106 8 : : btn(int(btn)), text(text), accent(accent), leftSide(leftSide), role(role) {}
107 : };
108 : using ButtonDatas = std::vector<ButtonData>;
109 :
110 : enum class TextFormat {
111 : Auto = 0,
112 : PlainText,
113 : RichText
114 : };
115 :
116 : struct Text {
117 : std::string text;
118 : TextFormat format = TextFormat::Auto;
119 : std::string detailedText;
120 :
121 8 : Text() = default;
122 0 : Text(const char* t)
123 0 : : text(t), format(TextFormat::Auto) {}
124 138 : Text(const std::string& t, const TextFormat& f = TextFormat::Auto)
125 81 : : text(t), format(f) {}
126 : };
127 :
128 : struct Result
129 : {
130 23 : Result() = default;
131 64 : Result(const int& button)
132 64 : : m_button(button) {}
133 2 : Result(const int& button, bool showAgain)
134 2 : : m_button(button), m_showAgain(showAgain) {}
135 :
136 7 : Button standardButton() const { return static_cast<Button>(m_button); }
137 7 : int button() const { return m_button; }
138 36 : bool isButton(int b) const { return b == m_button; }
139 12 : bool isButton(Button b) const { return static_cast<int>(b) == m_button; }
140 :
141 6 : bool showAgain() const { return m_showAgain; }
142 :
143 : private:
144 : int m_button = int(Button::NoButton);
145 : bool m_showAgain = true;
146 : };
147 :
148 : enum Option {
149 : NoOptions = 0x0,
150 : WithIcon = 0x1,
151 : WithDontShowAgainCheckBox = 0x2
152 : };
153 : DECLARE_FLAGS(Options, Option)
154 :
155 : // buttons data
156 : virtual ButtonData buttonData(Button b) const = 0;
157 9 : inline ButtonDatas buttonDataList(const Buttons& buttons) const
158 : {
159 9 : ButtonDatas result;
160 9 : result.reserve(buttons.size());
161 :
162 32 : for (Button b : buttons) {
163 23 : result.push_back(buttonData(b));
164 : }
165 :
166 9 : return result;
167 0 : }
168 :
169 : // question
170 : virtual async::Promise<Result> question(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons,
171 : int defBtn = int(Button::NoButton), const Options& options = {},
172 : const std::string& dialogTitle = {}) = 0;
173 :
174 0 : async::Promise<Result> question(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
175 : Button defBtn = Button::NoButton, const Options& options = {}, const std::string& dialogTitle = {})
176 : {
177 0 : return question(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
178 : }
179 :
180 : // info
181 : virtual async::Promise<Result> info(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
182 : int defBtn = int(Button::NoButton), const Options& options = {},
183 : const std::string& dialogTitle = {}) = 0;
184 :
185 : async::Promise<Result> info(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
186 : Button defBtn, const Options& options = {}, const std::string& dialogTitle = {})
187 : {
188 : return info(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
189 : }
190 :
191 : // warning
192 : virtual async::Promise<Result> warning(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
193 : int defBtn = int(Button::NoButton), const Options& options = { WithIcon },
194 : const std::string& dialogTitle = {}) = 0;
195 :
196 8 : async::Promise<Result> warning(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
197 : Button defBtn = Button::NoButton, const Options& options = { WithIcon },
198 : const std::string& dialogTitle = {})
199 : {
200 8 : return warning(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
201 : }
202 :
203 : // error
204 : virtual async::Promise<Result> error(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
205 : int defBtn = int(Button::NoButton), const Options& options = { WithIcon },
206 : const std::string& dialogTitle = {}) = 0;
207 :
208 1 : async::Promise<Result> error(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
209 : Button defBtn = Button::NoButton, const Options& options = { WithIcon },
210 : const std::string& dialogTitle = {})
211 : {
212 1 : return error(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
213 : }
214 :
215 : // progress
216 : virtual void showProgress(const std::string& title, Progress progress) = 0;
217 :
218 : // files
219 : virtual async::Promise<io::path_t> selectOpeningFile(const std::string& title, const io::path_t& dir,
220 : const std::vector<std::string>& filter) = 0;
221 : virtual io::path_t selectOpeningFileSync(const std::string& title, const io::path_t& dir, const std::vector<std::string>& filter,
222 : const int options = 0) = 0;
223 : virtual io::paths_t selectOpeningFilesSync(const std::string& title, const io::path_t& dir, const std::vector<std::string>& filter,
224 : const int options = 0) = 0;
225 : virtual async::Promise<io::path_t> selectSavingFile(const std::string& title, const io::path_t& path,
226 : const std::vector<std::string>& filter, bool confirmOverwrite = true) = 0;
227 : virtual io::path_t selectSavingFileSync(const std::string& title, const io::path_t& path, const std::vector<std::string>& filter,
228 : bool confirmOverwrite = true) = 0;
229 :
230 : // dirs
231 : virtual io::path_t selectDirectory(const std::string& title, const io::path_t& dir) = 0;
232 : virtual io::paths_t selectMultipleDirectories(const std::string& title, const io::path_t& dir,
233 : const io::paths_t& selectedDirectories) = 0;
234 :
235 : // color
236 : virtual async::Promise<Color> selectColor(const Color& color = Color::WHITE, const std::string& title = {},
237 : bool allowAlpha = false) = 0;
238 : virtual bool isSelectColorOpened() const = 0;
239 :
240 : // custom
241 : virtual async::Promise<Val> open(const UriQuery& uri) = 0;
242 5 : async::Promise<Val> open(const std::string& uri) { return open(UriQuery(uri)); }
243 22 : async::Promise<Val> open(const Uri& uri) { return open(UriQuery(uri)); }
244 : virtual RetVal<bool> isOpened(const UriQuery& uri) const = 0;
245 : virtual RetVal<bool> isOpened(const Uri& uri) const = 0;
246 : virtual async::Channel<Uri> opened() const = 0;
247 :
248 : virtual void raise(const UriQuery& uri) = 0;
249 :
250 : virtual async::Promise<Ret> close(const UriQuery& uri) = 0;
251 : virtual async::Promise<Ret> close(const Uri& uri) = 0;
252 : virtual Ret closeSync(const UriQuery& uri) = 0;
253 : virtual async::Promise<Ret> closeAllDialogs() = 0;
254 : virtual Ret closeAllDialogsSync() = 0;
255 :
256 : // state
257 : virtual ValCh<Uri> currentUri() const = 0;
258 : virtual RetVal<bool> isCurrentUriDialog() const = 0;
259 : virtual async::Notification currentUriAboutToBeChanged() const = 0;
260 : virtual std::vector<Uri> stack() const = 0;
261 :
262 : virtual QWindow* topWindow() const = 0;
263 : virtual bool topWindowIsWidget() const = 0;
264 :
265 : //! =================================
266 : //! NOTE Please don't use this
267 : //! =================================
268 : virtual Result questionSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons,
269 : int defBtn = int(Button::NoButton), const Options& options = {}, const std::string& dialogTitle = {}) = 0;
270 :
271 0 : Result questionSync(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
272 0 : const Button& defBtn = Button::NoButton, const Options& options = {}, const std::string& dialogTitle = {})
273 : {
274 0 : return questionSync(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
275 : }
276 :
277 : virtual Result infoSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
278 : int defBtn = int(Button::NoButton), const Options& options = {}, const std::string& dialogTitle = {}) = 0;
279 :
280 : Result infoSync(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
281 : const Button& defBtn = Button::NoButton, const Options& options = {}, const std::string& dialogTitle = {})
282 : {
283 : return infoSync(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
284 : }
285 :
286 : virtual Result warningSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
287 : int defBtn = int(Button::NoButton), const Options& options = { WithIcon },
288 : const std::string& dialogTitle = {}) = 0;
289 :
290 0 : Result warningSync(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
291 0 : const Button& defBtn = Button::NoButton, const Options& options = { WithIcon }, const std::string& dialogTitle = {})
292 : {
293 0 : return warningSync(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
294 : }
295 :
296 : virtual Result errorSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
297 : int defBtn = int(Button::NoButton), const Options& options = { WithIcon },
298 : const std::string& dialogTitle = {}) = 0;
299 :
300 : Result errorSync(const std::string& contentTitle, const std::string& text, const Buttons& buttons,
301 : const Button& defBtn = Button::NoButton, const Options& options = { WithIcon }, const std::string& dialogTitle = {})
302 : {
303 : return errorSync(contentTitle, Text(text), buttonDataList(buttons), (int)defBtn, options, dialogTitle);
304 : }
305 :
306 : virtual RetVal<Val> openSync(const UriQuery& uri) = 0;
307 12 : RetVal<Val> openSync(const std::string& uri) { return openSync(UriQuery(uri)); }
308 : RetVal<Val> openSync(const Uri& uri) { return openSync(UriQuery(uri)); }
309 : //! ==============================
310 : };
311 6 : DECLARE_OPERATORS_FOR_FLAGS(IInteractive::Options)
312 : }
|