QCodeEditor: Update to current cpeditor/QCodeEditor fork, commit ed1196a
[smuview.git] / src / python / uihelper.cpp
blobb428fb1e784e74cdaeb9506a1a67699b743d037f
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 <vector>
24 #include <QColor>
25 #include <QDebug>
26 #include <QInputDialog>
27 #include <QLineEdit>
28 #include <QMessageBox>
29 #include <QString>
31 #include "uihelper.hpp"
32 #include "src/mainwindow.hpp"
33 #include "src/session.hpp"
34 #include "src/channels/basechannel.hpp"
35 #include "src/data/analogtimesignal.hpp"
36 #include "src/devices/configurable.hpp"
37 #include "src/ui/tabs/basetab.hpp"
38 #include "src/ui/tabs/devicetab.hpp"
39 #include "src/ui/views/baseplotview.hpp"
40 #include "src/ui/views/baseview.hpp"
41 #include "src/ui/views/dataview.hpp"
42 #include "src/ui/views/powerpanelview.hpp"
43 #include "src/ui/views/timeplotview.hpp"
44 #include "src/ui/views/valuepanelview.hpp"
45 #include "src/ui/views/viewhelper.hpp"
46 #include "src/ui/views/xyplotview.hpp"
48 using std::shared_ptr;
49 using std::string;
51 namespace sv {
52 namespace python {
54 UiHelper::UiHelper(Session &session) :
55 session_(session)
57 // For the views_added signal.
58 qRegisterMetaType<std::vector<std::string>>("std::vector<std::string>");
61 void UiHelper::add_device_tab(shared_ptr<sv::devices::BaseDevice> device)
63 if (!session_.main_window()) {
64 Q_EMIT tab_added("");
65 return;
68 auto *tab = session_.main_window()->add_device_tab(device);
69 Q_EMIT tab_added(tab->id());
72 void UiHelper::add_data_view(const std::string &tab_id,
73 Qt::DockWidgetArea area,
74 shared_ptr<sv::data::AnalogTimeSignal> signal)
76 auto *tab = get_tab(tab_id);
77 if (!tab) {
78 Q_EMIT view_added("");
79 return;
82 auto *view = new ui::views::DataView(session_);
83 view->add_signal(signal);
84 tab->add_view(view, area);
85 Q_EMIT view_added(view->id());
88 void UiHelper::add_control_views(const std::string &tab_id,
89 Qt::DockWidgetArea area,
90 shared_ptr<sv::devices::Configurable> configurable)
92 std::vector<std::string> view_ids;
94 auto *tab = get_tab(tab_id);
95 if (!tab) {
96 Q_EMIT views_added(view_ids);
97 return;
99 auto views = ui::views::viewhelper::get_views_for_configurable(
100 session_, configurable);
101 if (views.empty()) {
102 Q_EMIT views_added(view_ids);
103 return;
106 for (const auto &view : views) {
107 tab->add_view(view, area);
108 view_ids.push_back(view->id());
110 Q_EMIT views_added(view_ids);
113 void UiHelper::add_time_plot_view(const std::string &tab_id,
114 Qt::DockWidgetArea area)
116 auto *tab = get_tab(tab_id);
117 if (!tab) {
118 Q_EMIT view_added("");
119 return;
122 auto *view = new ui::views::TimePlotView(session_);
123 tab->add_view(view, area);
124 Q_EMIT view_added(view->id());
127 void UiHelper::add_xy_plot_view(const std::string &tab_id,
128 Qt::DockWidgetArea area)
130 auto *tab = get_tab(tab_id);
131 if (!tab) {
132 Q_EMIT view_added("");
133 return;
136 auto *view = new ui::views::XYPlotView(session_);
137 tab->add_view(view, area);
138 Q_EMIT view_added(view->id());
141 void UiHelper::add_power_panel_view(const std::string &tab_id,
142 Qt::DockWidgetArea area,
143 shared_ptr<sv::data::AnalogTimeSignal> voltage_signal,
144 shared_ptr<sv::data::AnalogTimeSignal> current_signal)
146 auto *tab = get_tab(tab_id);
147 if (!tab) {
148 Q_EMIT view_added("");
149 return;
152 auto *view = new ui::views::PowerPanelView(session_);
153 view->set_signals(voltage_signal, current_signal);
154 tab->add_view(view, area);
155 Q_EMIT view_added(view->id());
158 void UiHelper::add_value_panel_view(const std::string &tab_id,
159 Qt::DockWidgetArea area,
160 shared_ptr<sv::channels::BaseChannel> channel)
162 auto *tab = get_tab(tab_id);
163 if (!tab) {
164 Q_EMIT view_added("");
165 return;
168 auto *view = new ui::views::ValuePanelView(session_);
169 view->set_channel(channel);
170 tab->add_view(view, area);
171 Q_EMIT view_added(view->id());
174 void UiHelper::add_value_panel_view(const std::string &tab_id,
175 Qt::DockWidgetArea area,
176 shared_ptr<sv::data::AnalogTimeSignal> signal)
178 auto *tab = get_tab(tab_id);
179 if (!tab) {
180 Q_EMIT view_added("");
181 return;
184 auto *view = new ui::views::ValuePanelView(session_);
185 view->set_signal(signal);
186 tab->add_view(view, area);
187 Q_EMIT view_added(view->id());
190 void UiHelper::add_signal_to_data_view(const std::string &tab_id,
191 const std::string &view_id,
192 shared_ptr<sv::data::AnalogTimeSignal> signal)
194 auto *view = get_view(tab_id, view_id);
195 if (!view)
196 return;
198 ((ui::views::DataView *)view)->add_signal(signal);
201 void UiHelper::set_channel_to_time_plot_view(const std::string &tab_id,
202 const std::string &view_id,
203 shared_ptr<sv::channels::BaseChannel> channel)
205 auto *plot_view = get_time_plot_view(tab_id, view_id);
206 if (!plot_view) {
207 Q_EMIT curve_added("");
208 return;
211 plot_view->set_channel(channel);
214 void UiHelper::add_curve_to_time_plot_view(const std::string &tab_id,
215 const std::string &view_id,
216 shared_ptr<sv::data::AnalogTimeSignal> signal)
218 auto *plot_view = get_time_plot_view(tab_id, view_id);
219 if (!plot_view) {
220 Q_EMIT curve_added("");
221 return;
224 string id = plot_view->add_signal(signal);
225 Q_EMIT curve_added(id);
228 void UiHelper::add_curve_to_xy_plot_view(const std::string &tab_id,
229 const std::string &view_id,
230 shared_ptr<sv::data::AnalogTimeSignal> x_signal,
231 shared_ptr<sv::data::AnalogTimeSignal> y_signal)
233 auto *view = get_view(tab_id, view_id);
234 if (!view) {
235 Q_EMIT curve_added("");
236 return;
238 auto *plot_view = qobject_cast<ui::views::XYPlotView *>(view);
239 if (!plot_view) {
240 qWarning() << "UiHelper::add_curve_to_xy_plot_view(): View is not a "
241 "xy plot view: " << QString::fromStdString(view_id);
242 Q_EMIT curve_added("");
243 return;
246 string id = plot_view->add_signals(x_signal, y_signal);
247 Q_EMIT curve_added(id);
250 void UiHelper::set_curve_name(const std::string &tab_id,
251 const std::string &view_id, const std::string &curve_id,
252 const std::string &name)
254 auto *plot_view = get_base_plot_view(tab_id, view_id);
255 if (!plot_view)
256 return;
258 bool ret = plot_view->set_curve_name(curve_id, QString::fromStdString(name));
259 if (!ret) {
260 qWarning() << "UiHelper::set_curve_name(): Curve not found: " <<
261 QString::fromStdString(curve_id);
265 void UiHelper::set_curve_color(const std::string &tab_id,
266 const std::string &view_id, const std::string &curve_id,
267 std::tuple<int, int, int> color)
269 auto *plot_view = get_base_plot_view(tab_id, view_id);
270 if (!plot_view)
271 return;
273 bool ret = plot_view->set_curve_color(curve_id,
274 QColor(std::get<0>(color), std::get<1>(color), std::get<2>(color)));
275 if (!ret) {
276 qWarning() << "UiHelper::set_curve_color(): Curve not found: " <<
277 QString::fromStdString(curve_id);
281 void UiHelper::show_message_box(const std::string &title,
282 const std::string &text)
284 if (!session_.main_window()) {
285 Q_EMIT message_box_canceled();
286 return;
289 auto button = QMessageBox::information(session_.main_window(),
290 QString::fromStdString(title), QString::fromStdString(text));
292 if (button == QMessageBox::StandardButton::Ok)
293 Q_EMIT message_box_finished();
294 else
295 Q_EMIT message_box_canceled();
298 void UiHelper::show_string_input_dialog(const std::string &title,
299 const std::string &label, const std::string &value)
301 if (!session_.main_window()) {
302 Q_EMIT input_dialog_canceled();
303 return;
306 bool ok;
307 QString str = QInputDialog::getText(session_.main_window(),
308 QString::fromStdString(title), QString::fromStdString(label),
309 QLineEdit::Normal, QString::fromStdString(value), &ok,
310 Qt::WindowFlags(), Qt::ImhNone);
312 if (ok)
313 Q_EMIT input_dialog_finished(QVariant(str));
314 else
315 Q_EMIT input_dialog_canceled();
319 void UiHelper::show_double_input_dialog(const std::string &title,
320 const std::string &label, double value, int decimals, double step,
321 double min, double max)
323 if (!session_.main_window()) {
324 Q_EMIT input_dialog_canceled();
325 return;
328 bool ok;
329 #if QT_VERSION >= QT_VERSION_CHECK(5, 10, 0)
330 double dec = QInputDialog::getDouble(session_.main_window(),
331 QString::fromStdString(title), QString::fromStdString(label),
332 value, min, max, decimals, &ok, Qt::WindowFlags(), step);
333 #else
334 (void)step;
335 double dec = QInputDialog::getDouble(session_.main_window(),
336 QString::fromStdString(title), QString::fromStdString(label),
337 value, min, max, decimals, &ok, Qt::WindowFlags());
338 #endif
340 if (ok)
341 Q_EMIT input_dialog_finished(QVariant(dec));
342 else
343 Q_EMIT input_dialog_canceled();
346 void UiHelper::show_int_input_dialog(const std::string &title,
347 const std::string &label, int value, int step, int min, int max)
349 if (!session_.main_window()) {
350 Q_EMIT input_dialog_canceled();
351 return;
354 bool ok;
355 int number = QInputDialog::getInt(session_.main_window(),
356 QString::fromStdString(title), QString::fromStdString(label),
357 value, min, max, step, &ok, Qt::WindowFlags());
359 if (ok)
360 Q_EMIT input_dialog_finished(QVariant(number));
361 else
362 Q_EMIT input_dialog_canceled();
365 ui::tabs::BaseTab *UiHelper::get_tab(const string &tab_id) const
367 if (!session_.main_window()) {
368 qWarning() << "UiHelper::get_tab(): No MainWindow found!";
369 return nullptr;
371 auto *tab = session_.main_window()->get_tab_from_tab_id(tab_id);
372 if (!tab) {
373 qWarning() << "UiHelper::get_tab(): Tab not found: " <<
374 QString::fromStdString(tab_id);
376 return tab;
379 ui::views::BaseView *UiHelper::get_view(const string &tab_id,
380 const string &view_id) const
382 auto *tab = get_tab(tab_id);
383 if (!tab)
384 return nullptr;
385 auto *view = tab->get_view_from_view_id(view_id);
386 if (!view) {
387 qWarning() << "UiHelper::get_view(): View not found: " <<
388 QString::fromStdString(view_id);
390 return view;
393 ui::views::BasePlotView *UiHelper::get_base_plot_view(const string &tab_id,
394 const string &view_id) const
396 auto *view = get_view(tab_id, view_id);
397 if (!view)
398 return nullptr;
399 auto *plot_view = qobject_cast<ui::views::BasePlotView *>(view);
400 if (!plot_view) {
401 qWarning() << "UiHelper::get_base_plot_view(): View is not a plot "
402 "view: " << QString::fromStdString(view_id);
404 return plot_view;
407 ui::views::TimePlotView *UiHelper::get_time_plot_view(const string &tab_id,
408 const string &view_id) const
410 auto *view = get_view(tab_id, view_id);
411 if (!view)
412 return nullptr;
413 auto *plot_view = qobject_cast<ui::views::TimePlotView *>(view);
414 if (!plot_view) {
415 qWarning() << "UiHelper::get_time_plot_view(): View is not a time plot "
416 "view: " << QString::fromStdString(view_id);
418 return plot_view;
421 } // namespace python
422 } // namespace sv