Loading...
Searching...
No Matches
MultiScriptEditor.hpp
1#pragma once
2#include <score/command/Dispatchers/CommandDispatcher.hpp>
3#include <score/command/PropertyCommand.hpp>
4#include <score/document/DocumentContext.hpp>
5#include <score/tools/Bind.hpp>
6
7#include <QCloseEvent>
8#include <QDialog>
9
10#include <score_lib_process_export.h>
11
12class QPlainTextEdit;
13class QTextEdit;
14class QTabWidget;
15
16namespace Process
17{
18class ProcessModel;
19class SCORE_LIB_PROCESS_EXPORT MultiScriptDialog : public QDialog
20{
21public:
22 MultiScriptDialog(const score::DocumentContext& ctx, QWidget* parent);
23
24 QSize sizeHint() const override { return {800, 300}; }
25 std::vector<QString> text() const noexcept;
26
27 void addTab(const QString& name, const QString& text, const std::string_view language);
28 void setText(int idx, const QString& str);
29 void setError(const QString& str);
30 void clearError();
31 void openInExternalEditor(const QString& editorPath);
32
33protected:
34 virtual void on_accepted() = 0;
35
36 void hideEvent(QHideEvent* event) override;
37 void keyPressEvent(QKeyEvent* event) override;
38
39 const score::DocumentContext& m_context;
40 QObject* m_compileFilter{};
41 QTabWidget* m_tabs{};
42 struct EditorTab
43 {
44 QTextEdit* textedit{};
45 };
46 std::vector<EditorTab> m_editors;
47 QPlainTextEdit* m_error{};
48};
49
50template <typename Process_T, typename Property_T>
52{
53public:
54 using param_type = typename Property_T::param_type;
56 const Process_T& process, const score::DocumentContext& ctx, QWidget* parent)
57 : MultiScriptDialog{ctx, parent}
58 , m_process{process}
59 {
60 const auto& prop = (m_process.*Property_T::get)();
61 for(auto& [name, addr, lang] : param_type::specification)
62 {
63 addTab(name, prop.*addr, lang);
64 }
65
66 con(m_process, Property_T::notify, this, [this]() {
67 const auto& prop = (m_process.*Property_T::get)();
68 int i = 0;
69 for(auto& [name, addr, lang] : param_type::specification)
70 {
71 setText(i, prop.*addr);
72 i++;
73 }
74 });
75
76 con(m_process, &Process_T::errorMessage, this,
77 &ProcessMultiScriptEditDialog::setError);
78 // The process goes first when its document closes: the dialog can still
79 // get closed after that (with the document's view) and must not look at
80 // it any more.
82 [this] {
83 m_processGone = true;
84 deleteLater();
85 });
86 }
87
88 void on_accepted() override
89 {
90 this->clearError();
91 if(this->text() != (m_process.*Property_T::get)())
92 {
93 // TODO try to see if we can make this a bit more efficient,
94 // by passing the validated / transformed data to the command maybe ?
95 if(m_process.validate(this->text()))
96 {
97 CommandDispatcher<>{m_context.commandStack}.submit(
99 m_process, this->text(), m_context});
100 }
101 }
102 }
103
104protected:
105 const Process_T& m_process;
106 bool m_processGone{};
107
108 // See ProcessScriptEditDialog
109 void reject() override { close(); }
110
111 void closeEvent(QCloseEvent* event) override
112 {
113 if(!m_processGone && m_process.scriptUI == this)
114 {
115 const_cast<QWidget*&>(m_process.scriptUI) = nullptr;
116 m_process.scriptUIVisible(false);
117 }
118 event->accept();
119 }
120};
121
122}
The CommandDispatcher class.
Definition CommandDispatcher.hpp:13
void identified_object_destroying(IdentifiedObjectAbstract *o)
To be called by subclasses.
Definition MultiScriptEditor.hpp:20
Definition MultiScriptEditor.hpp:52
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
Definition MultiScriptEditor.hpp:43
Definition DocumentContext.hpp:18
Definition PropertyCommand.hpp:112