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 <QObject>
26 : #include <QVariant>
27 : #include <QMap>
28 : #include <QStack>
29 :
30 : #include "async/asyncable.h"
31 :
32 : #include "modularity/ioc.h"
33 : #include "ui/imainwindow.h"
34 : #include "ui/iuiconfiguration.h"
35 :
36 : #include "../iinteractive.h"
37 : #include "iinteractiveprovider.h"
38 : #include "iinteractiveuriregister.h"
39 :
40 : #include "muse_framework_config.h"
41 : #ifdef MUSE_MODULE_SHORTCUTS_V2
42 : #include "shortcuts_v2/ishortcutscontroller.h"
43 : #else
44 : #include "shortcuts/ishortcutsregister.h"
45 : #endif
46 :
47 : namespace muse::interactive {
48 : class Interactive : public QObject, public IInteractive, public IInteractiveProvider, public Contextable, public async::Asyncable
49 : {
50 : Q_OBJECT
51 :
52 : GlobalInject<ui::IUiConfiguration> uiConfiguration;
53 : GlobalInject<interactive::IInteractiveUriRegister> uriRegister;
54 : #ifdef MUSE_MODULE_SHORTCUTS_V2
55 : ContextInject<shortcuts::IShortcutsController> shortcutsController = { this };
56 : #else
57 : ContextInject<shortcuts::IShortcutsRegister> shortcutsRegister = { this };
58 : #endif
59 : ContextInject<ui::IMainWindow> mainWindow = { this };
60 :
61 : public:
62 : explicit Interactive(const muse::modularity::ContextPtr& ctx);
63 :
64 : ButtonData buttonData(Button b) const override;
65 :
66 : // question
67 : Result questionSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons, int defBtn = int(Button::NoButton),
68 : const Options& options = {}, const std::string& dialogTitle = "") override;
69 :
70 : async::Promise<Result> question(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons,
71 : int defBtn = int(Button::NoButton), const Options& options = {},
72 : const std::string& dialogTitle = "") override;
73 :
74 : // info
75 : Result infoSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons, int defBtn = int(Button::NoButton),
76 : const Options& options = {}, const std::string& dialogTitle = "") override;
77 :
78 : async::Promise<Result> info(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
79 : int defBtn = int(Button::NoButton), const Options& options = {},
80 : const std::string& dialogTitle = "") override;
81 :
82 : // warning
83 : Result warningSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons, int defBtn = int(Button::NoButton),
84 : const Options& options = {}, const std::string& dialogTitle = "") override;
85 :
86 : async::Promise<Result> warning(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
87 : int defBtn = int(Button::NoButton), const Options& options = {},
88 : const std::string& dialogTitle = "") override;
89 :
90 : // error
91 : Result errorSync(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons, int defBtn = int(Button::NoButton),
92 : const Options& options = { WithIcon }, const std::string& dialogTitle = "") override;
93 :
94 : async::Promise<Result> error(const std::string& contentTitle, const Text& text, const ButtonDatas& buttons = {},
95 : int defBtn = int(Button::NoButton), const Options& options = { WithIcon },
96 : const std::string& dialogTitle = "") override;
97 :
98 : // progress
99 : void showProgress(const std::string& title, Progress progress) override;
100 :
101 : // files
102 : async::Promise<io::path_t> selectOpeningFile(const std::string& title, const io::path_t& dir,
103 : const std::vector<std::string>& filter) override;
104 : io::path_t selectOpeningFileSync(const std::string& title, const io::path_t& dir, const std::vector<std::string>& filter,
105 : const int options) override;
106 : io::paths_t selectOpeningFilesSync(const std::string& title, const io::path_t& dir, const std::vector<std::string>& filter,
107 : const int options) override;
108 : async::Promise<io::path_t> selectSavingFile(const std::string& title, const io::path_t& path, const std::vector<std::string>& filter,
109 : bool confirmOverwrite = true) override;
110 : io::path_t selectSavingFileSync(const std::string& title, const io::path_t& path, const std::vector<std::string>& filter,
111 : bool confirmOverwrite = true) override;
112 :
113 : // dirs
114 : io::path_t selectDirectory(const std::string& title, const io::path_t& dir) override;
115 : io::paths_t selectMultipleDirectories(const std::string& title, const io::path_t& dir, const io::paths_t& selectedDirectories) override;
116 :
117 : // color
118 : async::Promise<Color> selectColor(const Color& color = Color::WHITE, const std::string& title = {}, bool allowAlpha = false) override;
119 : bool isSelectColorOpened() const override;
120 :
121 : // custom
122 : RetVal<Val> openSync(const UriQuery& uri) override;
123 : async::Promise<Val> open(const UriQuery& uri) override;
124 : RetVal<bool> isOpened(const UriQuery& uri) const override;
125 : RetVal<bool> isOpened(const Uri& uri) const override;
126 : async::Channel<Uri> opened() const override;
127 :
128 : void raise(const UriQuery& uri) override;
129 :
130 : async::Promise<Ret> close(const UriQuery& uri) override;
131 : async::Promise<Ret> close(const Uri& uri) override;
132 : Ret closeSync(const UriQuery& uri) override;
133 : async::Promise<Ret> closeAllDialogs() override;
134 : Ret closeAllDialogsSync() override;
135 :
136 : // state
137 : ValCh<Uri> currentUri() const override;
138 : RetVal<bool> isCurrentUriDialog() const override;
139 : async::Notification currentUriAboutToBeChanged() const override;
140 : std::vector<Uri> stack() const override;
141 :
142 : QWindow* topWindow() const override;
143 : bool topWindowIsWidget() const override;
144 :
145 : // IInteractiveProvider interface
146 : QString objectId(const QVariant& val) const override;
147 :
148 : void onOpen(const QVariant& type, const QVariant& objectId, QObject* window = nullptr) override;
149 : void onClose(const QString& objectId, const QVariant& rv) override;
150 :
151 0 : async::Channel<QmlLaunchData*> openRequested() const override { return m_openRequested; }
152 0 : async::Channel<QVariant> closeRequested() const override { return m_closeRequested; }
153 0 : async::Channel<QVariant> raiseRequested() const override { return m_raiseRequested; }
154 :
155 : private:
156 : struct OpenData {
157 : QString objectId;
158 : };
159 :
160 : struct ObjectInfo {
161 : UriQuery query;
162 : async::Promise<Val>::Resolve resolve;
163 : async::Promise<Val>::Reject reject;
164 : QVariant objectId;
165 : QObject* window = nullptr;
166 : };
167 :
168 : async::Promise<Val> openAsync(const UriQuery& uri);
169 : async::Promise<Val> openAsync(const Uri& uri, const QVariantMap& params);
170 :
171 : async::Promise<Val>::BodyResolveReject openFunc(const UriQuery& q);
172 : async::Promise<Val>::BodyResolveReject openFunc(const UriQuery& q, const QVariantMap& params);
173 :
174 : void raiseWindowInStack(QObject* newActiveWindow);
175 :
176 : void fillData(QmlLaunchData* data, const Uri& uri, const QVariantMap& params) const;
177 : void fillData(QObject* object, const QVariantMap& params) const;
178 :
179 : Ret toRet(const QVariant& jsr) const;
180 : RetVal<Val> toRetVal(const QVariant& jsrv) const;
181 :
182 : RetVal<bool> isOpened(const QString& objectId) const;
183 :
184 : RetVal<OpenData> openWidgetDialog(const Uri& uri, const QVariantMap& params);
185 : RetVal<OpenData> openQml(const Uri& uri, const QVariantMap& params);
186 :
187 : async::Promise<Ret> closeObjects(const std::vector<ObjectInfo>& objs);
188 : Ret closeObjectsSync(const std::vector<ObjectInfo>& objs);
189 :
190 : void closeQml(const QVariant& objectId);
191 : void raiseQml(const QVariant& objectId);
192 :
193 : std::vector<ObjectInfo> allOpenObjects() const;
194 : std::vector<ObjectInfo> collectOpenObjects(std::function<bool(const ObjectInfo&)> accepted) const;
195 : std::vector<ObjectInfo> openDialogs() const;
196 :
197 : void notifyAboutCurrentUriChanged();
198 : void notifyAboutCurrentUriWillBeChanged();
199 :
200 : UriQuery makeQuery(const std::string& type, const std::string& contentTitle, const Text& text, const ButtonDatas& buttons, int defBtn,
201 : const Options& options, const std::string& dialogTitle) const;
202 :
203 : IInteractive::Result makeResult(const Val& val) const;
204 :
205 : async::Promise<IInteractive::Result> openStandardAsync(const std::string& type, const std::string& contentTitle, const Text& text,
206 : const ButtonDatas& buttons, int defBtn, const Options& options,
207 : const std::string& dialogTitle);
208 :
209 : IInteractive::Result openStandardSync(const std::string& type, const std::string& contentTitle, const Text& text,
210 : const ButtonDatas& buttons, int defBtn, const Options& options, const std::string& dialogTitle);
211 :
212 : ObjectInfo m_openingObject;
213 :
214 : QStack<ObjectInfo> m_stack;
215 : std::vector<ObjectInfo> m_floatingObjects;
216 :
217 : async::Channel<Uri> m_currentUriChanged;
218 : async::Notification m_currentUriAboutToBeChanged;
219 : async::Channel<Uri> m_opened;
220 :
221 : async::Channel<QmlLaunchData*> m_openRequested;
222 : async::Channel<QVariant> m_closeRequested;
223 : async::Channel<QVariant> m_raiseRequested;
224 :
225 : std::map<QString /*objectId*/, std::function<void(const Ret&)> > m_onClosedFuncs;
226 :
227 : bool m_isSelectColorOpened = false;
228 : };
229 : }
|