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/>.
23 #include <pybind11/pybind11.h>
26 #include <QDockWidget>
28 #include <QMetaObject>
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
;
46 namespace py
= pybind11
;
51 UiProxy::UiProxy(Session
&session
, shared_ptr
<UiHelper
> 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
)
108 init_wait_for_tab_added(id
);
109 Q_EMIT
add_device_tab(device
);
111 finish_wait_for_signal();
116 string
UiProxy::ui_add_data_view(const string
&tab_id
, Qt::DockWidgetArea area
,
117 shared_ptr
<data::AnalogTimeSignal
> signal
)
120 init_wait_for_view_added(id
);
121 Q_EMIT
add_data_view(tab_id
, area
, signal
);
123 finish_wait_for_signal();
128 vector
<string
> UiProxy::ui_add_control_views(const string
&tab_id
,
129 Qt::DockWidgetArea area
,
130 shared_ptr
<devices::Configurable
> configurable
)
133 init_wait_for_views_added(ids
);
134 Q_EMIT
add_control_views(tab_id
, area
, configurable
);
136 finish_wait_for_signal();
141 string
UiProxy::ui_add_time_plot_view(const string
&tab_id
,
142 Qt::DockWidgetArea area
)
145 init_wait_for_view_added(id
);
146 Q_EMIT
add_time_plot_view(tab_id
, area
);
148 finish_wait_for_signal();
153 string
UiProxy::ui_add_xy_plot_view(const string
&tab_id
,
154 Qt::DockWidgetArea area
)
157 init_wait_for_view_added(id
);
158 Q_EMIT
add_xy_plot_view(tab_id
, area
);
160 finish_wait_for_signal();
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
)
171 init_wait_for_view_added(id
);
172 Q_EMIT
add_power_panel_view(tab_id
, area
, voltage_signal
, current_signal
);
174 finish_wait_for_signal();
179 string
UiProxy::ui_add_value_panel_view(const string
&tab_id
,
180 Qt::DockWidgetArea area
,
181 shared_ptr
<channels::BaseChannel
> channel
)
184 init_wait_for_view_added(id
);
185 Q_EMIT
add_value_panel_view(tab_id
, area
, channel
);
187 finish_wait_for_signal();
192 string
UiProxy::ui_add_value_panel_view(const string
&tab_id
,
193 Qt::DockWidgetArea area
,
194 shared_ptr
<data::AnalogTimeSignal
> signal
)
197 init_wait_for_view_added(id
);
198 Q_EMIT
add_value_panel_view(tab_id
, area
, signal
);
200 finish_wait_for_signal();
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
)
224 init_wait_for_curve_added(id
);
225 Q_EMIT
add_curve_to_time_plot_view(tab_id
, view_id
, signal
);
227 finish_wait_for_signal();
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
)
238 init_wait_for_curve_added(id
);
239 Q_EMIT
add_curve_to_xy_plot_view(tab_id
, view_id
, x_signal
, y_signal
);
241 finish_wait_for_signal();
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
)
263 init_wait_for_message_box(ok
);
264 Q_EMIT
show_message_box(title
, text
);
266 finish_wait_for_signal();
271 py::object
UiProxy::ui_show_string_input_dialog(const string
&title
,
272 const string
&label
, const string
&value
)
276 init_wait_for_input_dialog(ok
, qvar
);
277 Q_EMIT
show_string_input_dialog(title
, label
, value
);
279 finish_wait_for_signal();
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
)
292 init_wait_for_input_dialog(ok
, qvar
);
293 Q_EMIT
show_double_input_dialog(
294 title
, label
, value
, decimals
, step
, min
, max
);
296 finish_wait_for_signal();
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
)
308 init_wait_for_input_dialog(ok
, qvar
);
309 Q_EMIT
show_int_input_dialog(title
, label
, value
, step
, min
, max
);
311 finish_wait_for_signal();
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
) {
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
) {
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
) {
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
) {
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,
394 event_loop_canceled_conn_
=
395 connect(ui_helper_
.get(), &UiHelper::message_box_canceled
, this,
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
) {
418 event_loop_canceled_conn_
=
419 connect(ui_helper_
.get(), &UiHelper::input_dialog_canceled
, this,
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_
);
440 disconnect(timer_conn_
);
443 } // namespace python