QCodeEditor: Update to current cpeditor/QCodeEditor fork, commit ed1196a
[smuview.git] / src / python / uiproxy.cpp
blob4a9183082a10afe6f2b387b948d43688126e0157
1 /*
2 * This file is part of the SmuView project.
4 * Copyright (C) 2019-2021 Frank Stettner <frank-stettner@gmx.net>
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include <memory>
21 #include <string>
22 #include <tuple>
23 #include <pybind11/pybind11.h>
25 #include <QDebug>
26 #include <QDockWidget>
27 #include <QEventLoop>
28 #include <QMetaObject>
29 #include <QTimer>
30 #include <QVariant>
32 #include "uiproxy.hpp"
33 #include "src/mainwindow.hpp"
34 #include "src/session.hpp"
35 #include "src/channels/basechannel.hpp"
36 #include "src/data/analogtimesignal.hpp"
37 #include "src/devices/basedevice.hpp"
38 #include "src/devices/configurable.hpp"
39 #include "src/python/uihelper.hpp"
40 #include "src/ui/tabs/basetab.hpp"
42 using std::shared_ptr;
43 using std::string;
44 using std::tuple;
46 namespace py = pybind11;
48 namespace sv {
49 namespace python {
51 UiProxy::UiProxy(Session &session, shared_ptr<UiHelper> ui_helper) :
52 session_(session),
53 ui_helper_(ui_helper)
55 // For the colors tuple:
56 qRegisterMetaType<std::tuple<int, int, int>>("std::tuple<int, int, int>");
58 connect(this, &UiProxy::add_device_tab,
59 ui_helper_.get(), &UiHelper::add_device_tab);
61 connect(this, &UiProxy::add_data_view,
62 ui_helper_.get(), &UiHelper::add_data_view);
64 connect(this, &UiProxy::add_control_views,
65 ui_helper_.get(), &UiHelper::add_control_views);
67 connect(this, &UiProxy::add_time_plot_view,
68 ui_helper_.get(), &UiHelper::add_time_plot_view);
69 connect(this, &UiProxy::add_xy_plot_view,
70 ui_helper_.get(), &UiHelper::add_xy_plot_view);
72 connect(this, &UiProxy::add_power_panel_view,
73 ui_helper_.get(), &UiHelper::add_power_panel_view);
75 connect(this, QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::channels::BaseChannel>>::of(&UiProxy::add_value_panel_view),
76 ui_helper_.get(), QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::channels::BaseChannel>>::of(&UiHelper::add_value_panel_view));
77 connect(this, QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::data::AnalogTimeSignal>>::of(&UiProxy::add_value_panel_view),
78 ui_helper_.get(), QOverload<const std::string &, Qt::DockWidgetArea, shared_ptr<sv::data::AnalogTimeSignal>>::of(&UiHelper::add_value_panel_view));
80 connect(this, &UiProxy::add_signal_to_data_view,
81 ui_helper_.get(), &UiHelper::add_signal_to_data_view);
83 connect(this, &UiProxy::set_channel_to_time_plot_view,
84 ui_helper_.get(), &UiHelper::set_channel_to_time_plot_view);
85 connect(this, &UiProxy::add_curve_to_time_plot_view,
86 ui_helper_.get(), &UiHelper::add_curve_to_time_plot_view);
87 connect(this, &UiProxy::add_curve_to_xy_plot_view,
88 ui_helper_.get(), &UiHelper::add_curve_to_xy_plot_view);
89 connect(this, &UiProxy::set_curve_name,
90 ui_helper_.get(), &UiHelper::set_curve_name);
91 connect(this, &UiProxy::set_curve_color,
92 ui_helper_.get(), &UiHelper::set_curve_color);
94 connect(this, &UiProxy::show_message_box,
95 ui_helper_.get(), &UiHelper::show_message_box);
96 connect(this, &UiProxy::show_string_input_dialog,
97 ui_helper_.get(), &UiHelper::show_string_input_dialog);
98 connect(this, &UiProxy::show_double_input_dialog,
99 ui_helper_.get(), &UiHelper::show_double_input_dialog);
100 connect(this, &UiProxy::show_int_input_dialog,
101 ui_helper_.get(), &UiHelper::show_int_input_dialog);
105 string UiProxy::ui_add_device_tab(shared_ptr<devices::BaseDevice> device)
107 string id;
108 init_wait_for_tab_added(id);
109 Q_EMIT add_device_tab(device);
110 event_loop_.exec();
111 finish_wait_for_signal();
113 return id;
116 string UiProxy::ui_add_data_view(const string &tab_id, Qt::DockWidgetArea area,
117 shared_ptr<data::AnalogTimeSignal> signal)
119 string id;
120 init_wait_for_view_added(id);
121 Q_EMIT add_data_view(tab_id, area, signal);
122 event_loop_.exec();
123 finish_wait_for_signal();
125 return id;
128 vector<string> UiProxy::ui_add_control_views(const string &tab_id,
129 Qt::DockWidgetArea area,
130 shared_ptr<devices::Configurable> configurable)
132 vector<string> ids;
133 init_wait_for_views_added(ids);
134 Q_EMIT add_control_views(tab_id, area, configurable);
135 event_loop_.exec();
136 finish_wait_for_signal();
138 return ids;
141 string UiProxy::ui_add_time_plot_view(const string &tab_id,
142 Qt::DockWidgetArea area)
144 string id;
145 init_wait_for_view_added(id);
146 Q_EMIT add_time_plot_view(tab_id, area);
147 event_loop_.exec();
148 finish_wait_for_signal();
150 return id;
153 string UiProxy::ui_add_xy_plot_view(const string &tab_id,
154 Qt::DockWidgetArea area)
156 string id;
157 init_wait_for_view_added(id);
158 Q_EMIT add_xy_plot_view(tab_id, area);
159 event_loop_.exec();
160 finish_wait_for_signal();
162 return id;
165 string UiProxy::ui_add_power_panel_view(const string &tab_id,
166 Qt::DockWidgetArea area,
167 shared_ptr<data::AnalogTimeSignal> voltage_signal,
168 shared_ptr<data::AnalogTimeSignal> current_signal)
170 string id;
171 init_wait_for_view_added(id);
172 Q_EMIT add_power_panel_view(tab_id, area, voltage_signal, current_signal);
173 event_loop_.exec();
174 finish_wait_for_signal();
176 return id;
179 string UiProxy::ui_add_value_panel_view(const string &tab_id,
180 Qt::DockWidgetArea area,
181 shared_ptr<channels::BaseChannel> channel)
183 string id;
184 init_wait_for_view_added(id);
185 Q_EMIT add_value_panel_view(tab_id, area, channel);
186 event_loop_.exec();
187 finish_wait_for_signal();
189 return id;
192 string UiProxy::ui_add_value_panel_view(const string &tab_id,
193 Qt::DockWidgetArea area,
194 shared_ptr<data::AnalogTimeSignal> signal)
196 string id;
197 init_wait_for_view_added(id);
198 Q_EMIT add_value_panel_view(tab_id, area, signal);
199 event_loop_.exec();
200 finish_wait_for_signal();
202 return id;
205 void UiProxy::ui_add_signal_to_data_view(const string &tab_id,
206 const string &view_id,
207 shared_ptr<data::AnalogTimeSignal> signal)
209 Q_EMIT add_signal_to_data_view(tab_id, view_id, signal);
212 void UiProxy::ui_set_channel_to_time_plot_view(const string &tab_id,
213 const string &view_id,
214 shared_ptr<channels::BaseChannel> channel)
216 Q_EMIT set_channel_to_time_plot_view(tab_id, view_id, channel);
219 string UiProxy::ui_add_curve_to_time_plot_view(const string &tab_id,
220 const string &view_id,
221 shared_ptr<data::AnalogTimeSignal> signal)
223 string id;
224 init_wait_for_curve_added(id);
225 Q_EMIT add_curve_to_time_plot_view(tab_id, view_id, signal);
226 event_loop_.exec();
227 finish_wait_for_signal();
229 return id;
232 string UiProxy::ui_add_curve_to_xy_plot_view(const string &tab_id,
233 const string &view_id,
234 shared_ptr<data::AnalogTimeSignal> x_signal,
235 shared_ptr<data::AnalogTimeSignal> y_signal)
237 string id;
238 init_wait_for_curve_added(id);
239 Q_EMIT add_curve_to_xy_plot_view(tab_id, view_id, x_signal, y_signal);
240 event_loop_.exec();
241 finish_wait_for_signal();
243 return id;
246 void UiProxy::ui_set_curve_name(const string &tab_id, const string &view_id,
247 const string &curve_id, const string &name)
249 Q_EMIT set_curve_name(tab_id, view_id, curve_id, name);
252 void UiProxy::ui_set_curve_color(const string &tab_id, const string &view_id,
253 const string &curve_id, tuple<int, int, int> color)
255 Q_EMIT set_curve_color(tab_id, view_id, curve_id, color);
259 bool UiProxy::ui_show_message_box(const std::string &title,
260 const std::string &text)
262 bool ok;
263 init_wait_for_message_box(ok);
264 Q_EMIT show_message_box(title, text);
265 event_loop_.exec();
266 finish_wait_for_signal();
268 return ok;
271 py::object UiProxy::ui_show_string_input_dialog(const string &title,
272 const string &label, const string &value)
274 bool ok;
275 QVariant qvar;
276 init_wait_for_input_dialog(ok, qvar);
277 Q_EMIT show_string_input_dialog(title, label, value);
278 event_loop_.exec();
279 finish_wait_for_signal();
281 if (!ok)
282 return py::cast<py::none>(Py_None);
283 return py::cast(qvar.toString().toStdString());
286 py::object UiProxy::ui_show_double_input_dialog(const string &title,
287 const string &label, double value, int decimals, double step,
288 double min, double max)
290 bool ok;
291 QVariant qvar;
292 init_wait_for_input_dialog(ok, qvar);
293 Q_EMIT show_double_input_dialog(
294 title, label, value, decimals, step, min, max);
295 event_loop_.exec();
296 finish_wait_for_signal();
298 if (!ok)
299 return py::cast<py::none>(Py_None);
300 return py::cast(qvar.toDouble());
303 py::object UiProxy::ui_show_int_input_dialog(const string &title,
304 const string &label, int value, int step, int min, int max)
306 bool ok;
307 QVariant qvar;
308 init_wait_for_input_dialog(ok, qvar);
309 Q_EMIT show_int_input_dialog(title, label, value, step, min, max);
310 event_loop_.exec();
311 finish_wait_for_signal();
313 if (!ok)
314 return py::cast<py::none>(Py_None);
315 return py::cast(qvar.toInt());
318 void UiProxy::init_wait_for_tab_added(string &id, int timeout)
320 event_loop_finished_conn_ =
321 connect(ui_helper_.get(), &UiHelper::tab_added, this,
322 [this, &id](const std::string &tab_id) {
323 id = tab_id;
324 event_loop_.quit();
327 if (timeout > 0) {
328 timer_.setSingleShot(true);
329 timer_conn_ = connect(&timer_, &QTimer::timeout,
330 &event_loop_, &QEventLoop::quit);
331 timer_.start(timeout);
335 void UiProxy::init_wait_for_view_added(string &id, int timeout)
337 event_loop_finished_conn_ =
338 connect(ui_helper_.get(), &UiHelper::view_added, this,
339 [this, &id](const std::string &view_id) {
340 id = view_id;
341 event_loop_.quit();
344 if (timeout > 0) {
345 timer_.setSingleShot(true);
346 timer_conn_ = connect(&timer_, &QTimer::timeout,
347 &event_loop_, &QEventLoop::quit);
348 timer_.start(timeout);
352 void UiProxy::init_wait_for_views_added(vector<string> &ids, int timeout)
354 event_loop_finished_conn_ =
355 connect(ui_helper_.get(), &UiHelper::views_added, this,
356 [this, &ids](const vector<std::string> &view_ids) {
357 ids = view_ids;
358 event_loop_.quit();
361 if (timeout > 0) {
362 timer_.setSingleShot(true);
363 timer_conn_ = connect(&timer_, &QTimer::timeout,
364 &event_loop_, &QEventLoop::quit);
365 timer_.start(timeout);
369 void UiProxy::init_wait_for_curve_added(string &id, int timeout)
371 event_loop_finished_conn_ =
372 connect(ui_helper_.get(), &UiHelper::curve_added, this,
373 [this, &id](const std::string &curve_id) {
374 id = curve_id;
375 event_loop_.quit();
378 if (timeout > 0) {
379 timer_.setSingleShot(true);
380 timer_conn_ = connect(&timer_, &QTimer::timeout,
381 &event_loop_, &QEventLoop::quit);
382 timer_.start(timeout);
386 void UiProxy::init_wait_for_message_box(bool &ok, int timeout)
388 event_loop_finished_conn_ =
389 connect(ui_helper_.get(), &UiHelper::message_box_finished, this,
390 [this, &ok]() {
391 ok = true;
392 event_loop_.quit();
394 event_loop_canceled_conn_ =
395 connect(ui_helper_.get(), &UiHelper::message_box_canceled, this,
396 [this, &ok]() {
397 ok = false;;
398 event_loop_.quit();
401 if (timeout > 0) {
402 timer_.setSingleShot(true);
403 timer_conn_ = connect(&timer_, &QTimer::timeout,
404 &event_loop_, &QEventLoop::quit);
405 timer_.start(timeout);
409 void UiProxy::init_wait_for_input_dialog(bool &ok, QVariant &qvar, int timeout)
411 event_loop_finished_conn_ =
412 connect(ui_helper_.get(), &UiHelper::input_dialog_finished, this,
413 [this, &ok, &qvar](const QVariant &qvar_input) {
414 ok = true;
415 qvar = qvar_input;
416 event_loop_.quit();
418 event_loop_canceled_conn_ =
419 connect(ui_helper_.get(), &UiHelper::input_dialog_canceled, this,
420 [this, &ok]() {
421 ok = false;;
422 event_loop_.quit();
425 if (timeout > 0) {
426 timer_.setSingleShot(true);
427 timer_conn_ = connect(&timer_, &QTimer::timeout,
428 &event_loop_, &QEventLoop::quit);
429 timer_.start(timeout);
433 void UiProxy::finish_wait_for_signal()
435 if (event_loop_finished_conn_)
436 disconnect(event_loop_finished_conn_);
437 if (event_loop_canceled_conn_)
438 disconnect(event_loop_canceled_conn_);
439 if (timer_conn_)
440 disconnect(timer_conn_);
443 } // namespace python
444 } // namespace sv